JS -子元素不监听委托事件
JS - Child element to not listen to delegated event
在下面的代码片段中,您将看到一个委托事件附加到document
。
要注意的关键是:
if (e.target.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
function loadItems(target) {
for (var i = 0; i < 10; i++) {
setTimeout(function() {
target.insertAdjacentHTML('beforeend', '<div class="new"><span>Click me!</span>Or click me!</div>');
}, (i * 250));
}
}
document.getElementsByTagName('button')[0].addEventListener('click', function(e) {
loadItems(document.getElementById('put-stuff-here'));
});
document.addEventListener('click', function(e) {
if (e.target.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
});
body {
font-family: 'arial';
display: flex;
flex-flow: column;
}
body > * {
margin-bottom: 16px;
}
#put-stuff-here:before {
display: block;
padding: 8px;
text-align: center;
content: 'Target Location:';
background-color: PapayaWhip;
}
#put-stuff-here {
border: 1px solid black;
}
.new {
background-color: SteelBlue;
padding: 8px;
}
.new span {
border: 1px dotted red;
margin: 8px;
}
.active {
background-color: white;
}
<button>Press Me!</button>
<div id="put-stuff-here">
</div>
正如你所看到的,如果你点击"红边span",它将不起作用,但如果你点击div,它就起作用了。我知道原因,解决办法是:
if (e.target.parentNode.id === 'put-stuff-here' || e.target.parentNode.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
;但是,它不能完全工作,并导致以下情况(分别单击span和div):
function loadItems(target) {
for (var i = 0; i < 10; i++) {
setTimeout(function() {
target.insertAdjacentHTML('beforeend', '<div class="new"><span>New!</span></div>');
}, (i * 250));
}
}
document.getElementsByTagName('button')[0].addEventListener('click', function(e) {
loadItems(document.getElementById('put-stuff-here'));
});
document.addEventListener('click', function(e) {
if (e.target.parentNode.id === 'put-stuff-here' || e.target.parentNode.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
});
body {
font-family: 'arial';
display: flex;
flex-flow: column;
}
body > * {
margin-bottom: 16px;
}
#put-stuff-here:before {
display: block;
padding: 8px;
text-align: center;
content: 'Target Location:';
background-color: PapayaWhip;
}
#put-stuff-here {
border: 1px solid black;
}
.new {
background-color: SteelBlue;
padding: 8px;
}
.new span {
border: 1px dotted red;
margin: 8px;
}
.active {
background-color: white;
}
<button>Press Me!</button>
<div id="put-stuff-here">
</div>
我还测试了其他各种方法,包括:
if (e.target.parentNode.id === 'put-stuff-here' || e.target.parentNode.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active') || e.target.parentNode.classList.toggle('active');
}
但是他们都不做我想要的,这是:当你点击任何地方在div
,它会切换active
类
我认为解决方案在于某个地方事件冒泡,但我没能找到一种方法来利用这一点。是否有一种方法可以让子事件"忽略"(非)委托事件的事件处理程序?
可以在这里找到一个jsfile。
注:我知道另一种方法是:
if (e.target.classList.contains('new') || e.target.parentNode.classList.contains('new')) {
e.target.classList.toggle('active');
}
和所有其他的变化,等等,但这会遇到我上面列出的同样的问题
您可以使用pointer-events
:
CSS属性
pointer-events
允许作者控制在什么下在某些情况下(如果有的话),一个特定的图形元素可以成为鼠标事件目标。
.new > * {
pointer-events: none;
}
function loadItems(target) {
for (var i = 0; i < 10; i++) {
setTimeout(function() {
target.insertAdjacentHTML('beforeend', '<div class="new"><span>Click me!</span>Or click me!</div>');
}, (i * 250));
}
}
document.getElementsByTagName('button')[0].addEventListener('click', function(e) {
loadItems(document.getElementById('put-stuff-here'));
});
document.addEventListener('click', function(e) {
if (e.target.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
});
body {
font-family: 'arial';
display: flex;
flex-flow: column;
}
body > * {
margin-bottom: 16px;
}
#put-stuff-here:before {
display: block;
padding: 8px;
text-align: center;
content: 'Target Location:';
background-color: PapayaWhip;
}
#put-stuff-here {
border: 1px solid black;
}
.new {
background-color: SteelBlue;
padding: 8px;
}
.new > span {
border: 1px dotted red;
margin: 8px;
pointer-events: none;
}
.active {
background-color: white;
}
<button>Press Me!</button>
<div id="put-stuff-here">
</div>
我认为解决方案在于某个地方事件冒泡,但我没能找到一种方法来利用这一点。子事件是否有"忽略"的方法?(非)委托事件的事件处理程序?
是的,事件冒泡是解决方案的一部分,并且利用event.target
和event.currentTarget
的属性将帮助您沿着事件链隔离特定元素。
片段
// Reference the parent element
var parent = document.getElementById('parent');
// add an eventListener to the parent element
parent.addEventListener('click', function(event) {
/*
| While in bubbling phase, we only want event.target
| (i.e. the element that was clicked on) and not
| all of the other elements that happen to be on the
| event chain (i.e. event.currentTarget)
*/
if (event.target !== event.currentTarget) {
// Store the event.target in a var
var tgt = event.target;
// Do whatever you want to event.target
tgt.classList.toggle('active');
}
/*
| Stop any further bubbling so that event.target is
| the only element on the event chain that reacts to
| the click event.
*/
event.stopPropagation();
}, false);
#parent {
background: rgba(0, 0, 0, .75);
border: 3px dashed red;
padding: 10px;
}
.child {
background: rgba(255, 255, 255, .75);
border: 1px solid blue;
margin: 5px;
height: 15px;
}
.active {
background: red;
outline: 2px dotted orange;
}
<main id='parent'>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
<section class='child'></section>
</main>
相关文章:
- 如何在AngularJS中监听点击事件,而不是触摸事件
- 监听touchend有时会触发移动点击事件
- jQuery有没有,或者有没有jQuery插件,内置了监听CSS3动画事件的功能(例如animationEnd)
- 如何让Google Maps API v3监听dragend事件并在投递时填充表单字段
- 如何在angular js中监听dom就绪事件
- React鼠标事件在没有监听它们的组件上触发
- 如何在具体化 CSS 中监听<选择>更改事件
- 如何将誓言令牌推送到本地存储或本地会话并监听存储事件?(SoundCloud Php/JS 错误解决方法)
- 有没有办法在 asp.net MVC 3 中使用 JavaScript、Jquery 监听事件
- 一个“;监听路由器”;(响应视图/模型中的路由器事件)
- 谷歌聚合物监听火灾事件从未发生过
- 套接字.特定房间的IO事件监听
- larav 's事件监听和发射
- 什么's为href和'添加void(0)的效果;return false'锚点标记的点击事件监听
- 从DOM元素上的事件监听切换
- 在Angular中把事件监听放在哪里?
- JS-键盘事件-监听/取消监听
- 关于Kinetic JS的事件监听
- 如何在事件监听时在两个函数之间切换的标记中使用事件监听器
- Nodejs:如何处理对象之间的事件监听