简体   繁体   English

具有子节点的元素的Javascript委托

[英]Javascript delegate for elements with child nodes

In a simple example , I try to make delegate for first-level children of an element. 在一个简单的示例中 ,我尝试为元素的第一级子代创建委托。 The problem comes when the child elements have children. 当子元素有孩子时,问题就来了。 The mouse event consider the clicked element (regardless of level). 鼠标事件考虑了clicked元素(与级别无关)。

My solution is to cycle until reaching the first-level child; 我的解决方案是骑自行车直到到达一级孩子为止。 but I wonder if this is the best method to do so. 但是我想知道这是否是最好的方法。

Isn't there a method for directly returning the first-level children upon delegate click? 是否没有一种方法可以在委托单击时直接返回一级子级?

JS JS

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

HTML 的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>

If it's only the first level elements you're after, you could check if the parentNode of the clicked element is the root, no further traversing needed. 如果这只是您所关注的第一级元素,则可以检查clicked元素的parentNode是否为根,而无需进一步遍历。 Otherwise you'll need to traverse up to the first child of the root. 否则,您将需要遍历到根的第一个孩子。 Something like: 就像是:

// 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;  
}

Here is a fork of your jsfiddle , using the above. 这是使用上述代码的jsfiddle的一个分支。

I'm not sure what's beeing ask here. 我不确定在这里问什么。 Events do Bubble by default (which is actually not true, by default they would traverse top->down) because its most common to call .addEventListener with false as third argument. 默认情况下,事件会执行冒泡 (实际上不是真的,默认情况下,它们会从上到下进行遍历),因为调用.addEventListener时最常见的做法是将false作为第三个参数。

You can stop most events from further bubbling up, by calling eventObject.stopPropagation() on the node where you want to stop it. 通过在要停止事件的节点上调用eventObject.stopPropagation() ,可以阻止大多数事件进一步冒泡。

If you want to "prefilter" only the first-level children, you shouldn't use delegation at all, but query with .querySelectorAll like 如果您只想“过滤”第一级子级,则根本不应该使用委托,而应使用.querySelectorAll类的方法进行查询

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

That would bind click event listeners on all direct children from #test . 这会将点击事件侦听器绑定到#test所有直接子#test

See that in action: http://jsfiddle.net/8Xmn4/ 看到实际效果: http : //jsfiddle.net/8Xmn4/

using only javascript you can use a recursive function that will find the first parent element with an id: 仅使用javascript,您可以使用递归函数,该函数将找到具有ID的第一个父元素:

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

    return findParentWithId(element.parentNode);
}

​and then, use it with the target element of the event 然后,将其与事件的目标元素一起使用

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

Getting a reference to all first level children of a node is simple: 获得对节点的所有一级子级的引用很简单:

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

this outputs, on Firebug format: 以Firebug格式输出:

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

Obviously, it returns the children with their respective children, but the first level reference remains. 显然,它将返回子项及其各自的子项,但仍保留第一级参考。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM