<ul class="buy-list">
<li class="item">
<p class="sour-price">
<p class="source">京东商城</p>
<p class="price">¥1140</p>
</p>
<p class="desc-buylink">
<p class="desc">京东商城</p>
<p class="buylink">购买</p>
</p>
</li>
...
...
</ul>
上面的结构,ul下面有很多li,现在我把事件委托到ul上,
代码:
var buyList = document.querySelector('.buy-list');
buyList.onclick = function(e){
var target = e.target;
// 只有点击li才触发事件
if(target.className.indexOf('item') !== -1){
// do something
}
}
我想实现的效果是:点击li或li内部的任意一个元素,都会执行事件。
但是上面的写法只有当我点击li时才会执行do something,点击的是sour-price 或 price元素,都不会执行do something...
请问如何实现我想要的效果?
PS:当然,判断 target.parentNode
或 target.parentNode.parentNode
看看是不是li也是可以的,但老觉得这么写不优雅。假设li里的结构更加复杂的话,这样写就不行了,总不能N个parentNode,一直往上找吧?
首先要用
addEventListener
而不用onclick
,onclick
只能绑定一个事件,前者可以绑定多个。明确的回答你用jQuery,其中有相应的用法,.on()
搞清楚了 DOM 事件处理流程,其实永原生 JS 解决问题也不难。
via:dom-event-architecture
你没说清楚点击后执行什么样的事件?子元素的事件是会冒泡到父元素的,你在父元素上添加事件处理即可。
addEventListener用这个给li绑定事件
jQuery中的on方法可以选择标签
on()方法
直接给li这个element绑定事件:
li内部的任何子元素被点击,通过事件冒泡,li元素都会接受到这个点击事件。
第三个参数
useCapture = false
,表示handler被设置在冒泡阶段,子元素先被触发,父元素后被触发;当
useCapture = true
时,表示handler被设置在捕获阶段,父元素先被触发,子元素后被触发;另外因为这是li,所以估计你应该用
querySelectorAll
,在给它们绑定事件时可能会需要用到闭包,这里可以注意一下。//判断child是否在nodes中,或子元素;返回Number||-1
这个是我用的,nodes = 所有的li,child = e.target 对象,判断点击的对象是li的哪个子元素
onclick只是你绑定的DOM本身的一个事件回调(方法),并不涉及事件传递,所以我觉得这也并不能称为事件委托。委托还是要用addEventListener的(仅就原生来说,jQuery里就是on)
看题主,应该是想如何有简单的方法判断element1是否是element2的descendant,答案就是自己写一个利用parentNode的函数,详见stackoverflow
应该是事件冒泡问题引起的,同意zach5078的方案
判断target,当前触发事件的