本文介绍了Vanilla JS事件委托 - 处理目标元素的子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在香草JS中做事件委托。我在这样一个容器里面有一个按钮

 < div id =quiz> 
< button id =game-againclass =game-again>< span class =icon-spinner icon>< / span>< span>再次转到< / span> ;< /按钮>
< / div>

以下我正在添加一个事件处理程序到这个按钮的祖先,如下所示:

  this.container .addEventListener('click',function(e){
if(e.target&& e.target.id =='game-again'){
e.stopPropagation();
self.publish('primo:evento');
}
});

其中this.container是#quiz元素。这工作的一半时间,但其余的时间点击事件的目标是按钮之一的跨度,所以我的事件处理程序不被调用。

解决方案

较新的浏览器



较新的浏览器支持:

  this.container.addEventListener('click',function(e){
if( e.target.matches('#game-again,#game-again *')){
e.stopPropagation();
self.publish('primo:evento');
}
});

您可以使用

  var matches = document.body.matchesSelector || document.body.webkitMatchesSelector || document.body.mozMatchesSelector || document.body.msMatchesSelector || document.body.webkitMatchesSelector || document.body.matchesSelector 

然后使用 .apply 更多浏览器(仍然IE9 +)。



旧版浏览器



假设您必须支持旧版浏览器,你可以走DOM:

  function hasInParents(el,id){
if(el.id == = id)return true; //元素
if(element.parentNode)返回hasInParents(el.parentNode,id); // a parent
return false; //不是元素或其父母
}

然而,这将攀登整个dom ,你想停止代理目标:

  function hasInParentsUntil(el,id,limit){
if (el.id === id)return true; //元素
if(el === limit)return false;
if(element.parentNode)return hasInParents(el.parentNode,id); // a parent
return false; //不是元素和它的父母
}

哪些会使你的代码: / p>

  this.container.addEventListener('click',function(e){
if(hasInParentsUntil(e.target, 'game-again',container)){//容器应为
e.stopPropagation(); //可用于此
self.publish('primo:evento');
}
});


I'm trying to do event delegation in vanilla JS. I have a button inside a container like this

<div id="quiz">
    <button id="game-again" class="game-again"><span class="icon-spinner icon"></span><span>Go again</span></button>
</div>

And following David Walsh's nice instructions I'm adding an event handler to an ancestor of the button like so:

this.container.addEventListener('click', function(e){
    if (e.target && e.target.id == 'game-again') {
        e.stopPropagation();
        self.publish('primo:evento');
    }
});

Where this.container is the #quiz element. This works half the time, but the rest of the time the target of the click event is one of the spans inside the button, so my event handler isn't called. What's the best way to deal with this situation?

解决方案

Newer browsers

Newer browsers support .matches:

this.container.addEventListener('click', function(e){
    if (e.target.matches('#game-again,#game-again *')) {
        e.stopPropagation();
        self.publish('primo:evento');
    }
});

You can get the unprefixed version with

var matches = document.body.matchesSelector || document.body.webkitMatchesSelector || document.body.mozMatchesSelector || document.body.msMatchesSelector || document.body.webkitMatchesSelector || document.body.matchesSelector

And then use .apply for more browsers (Still IE9+).

Older browsers

Assuming you have to support older browsers, you can walk up the DOM:

function hasInParents(el,id){
    if(el.id === id) return true; // the element
    if(element.parentNode) return hasInParents(el.parentNode,id); // a parent
    return false; // not the element nor its parents
}

However, this will climb the whole dom, and you want to stop at the delegation target:

function hasInParentsUntil(el,id,limit){
    if(el.id === id) return true; // the element
    if(el === limit) return false;
    if(element.parentNode) return hasInParents(el.parentNode,id); // a parent
    return false; // not the element nor its parents
}

Which, would make your code:

this.container.addEventListener('click', function(e){
    if (hasInParentsUntil(e.target,'game-again',container)) { // container should be
        e.stopPropagation();                                  // available for this
        self.publish('primo:evento');
    }
});

这篇关于Vanilla JS事件委托 - 处理目标元素的子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:09