问题描述
我正在尝试在香草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事件委托 - 处理目标元素的子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!