Javascript委托具有子节点的元素

时间:2012-08-23 17:17:16

标签: javascript javascript-events

在一个简单的example中,我尝试为元素的第一级子节点创建委托。当子元素有子元素时会出现问题。鼠标事件考虑被点击的元素(无论级别如何)。

我的解决方案是循环直到达到一级孩子;但我想知道这是否是最好的方法。

是否有代表点击时直接返回第一级孩子的方法?

JS

window.onload=function(){
document.getElementById('test').addEventListener('click', function(e){
console.log(e.target);alert(e.target.id);
   }, false);
}

HTML

<div id="test">
<a href="#" id="first">First</a>
<a href="#" id="second"><b>Second</b></a>
<a href="#" id="third">Third</a>
<a href="#" id="fourth">Fourth</a>
<div id="div">Division</div>
<div id="div2"><span>Division</span></div>
</div>

5 个答案:

答案 0 :(得分:3)

如果它只是你所追求的第一级元素,你可以检查被点击元素的parentNode是否是根,不需要进一步的遍历。否则,您需要遍历根的第一个子节点。类似的东西:

// level0 is the root
level0.addEventListener('click', function(e) {
    var from = e.target || e.srcElement;
    from = from.parentNode === level0 ? from : findFirst(level0,from);
    /** do things **/
}, false);

// traverse up to first child of [root] 
function findFirst(root,el){
  while(true){
   el = el.parentNode;
   if (el && el.parentNode === root){
     return el;
   }
  }
  return null;  
}

以下是jsfiddle的分叉,使用上述内容。

答案 1 :(得分:1)

我不确定这里有什么问题。默认情况下事件冒泡(实际上不是这样,默认情况下它们将遍历top-&gt; down),因为最常见的是以.addEventListener作为第三个参数调用false

您可以通过在要停止它的节点上调用eventObject.stopPropagation()来阻止大多数事件进一步冒泡。

如果您只想“预过滤”第一级孩子,则根本不应使用委托,而是使用.querySelectorAll查询

[].forEach.call( document.querySelectorAll('#test > *'), function( node ) {
    node.addEventListener('click', function( event ) {
        alert( this.id );
    }, false);
});

这将绑定来自#test的所有直接子项的click事件侦听器。

查看实际操作:http://jsfiddle.net/8Xmn4/

答案 2 :(得分:1)

仅使用javascript,您可以使用递归函数,该函数将找到具有id的第一个父元素:

function findParentWithId(element){
    if(element.id){
        return element;
    }

    return findParentWithId(element.parentNode);
}

然后,将它与事件的目标元素一起使用

document.getElementById('test').addEventListener('click', function(e){
    console.log(findParentWithId(e.target));alert(findParentWithId(e.target).id);
}, false);

答案 3 :(得分:1)

获取节点的所有第一级子节点的引用很简单:

window.onload=function(){
    document.getElementById('test').addEventListener('click', function(e){
        return document.getElementById('test').children;
    }, false);
}

此输出,以Firebug格式:

[a#first #, a#second #, a#third #, a#fourth #, div#div, div#div]

显然,它会让孩子们和他们各自的孩子一起返回,但是第一级参考仍然存在。

答案 4 :(得分:0)

jQuery(':first-child') use this jquery to get the first child