在以下代码段中,您会看到附加到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>
正如您所看到的,如果您单击“红边跨度”它将无法工作,但如果您单击div它可以工作。我知道这个的原因和“解决方案”是:
if (e.target.parentNode.id === 'put-stuff-here' || e.target.parentNode.parentNode.id === 'put-stuff-here') {
e.target.classList.toggle('active');
}
此;但是,没有完全工作,并导致这个(点击跨度然后点击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
类
我认为解决方案存在于事件冒泡的地方,但我无法找到利用它的方法。有没有办法让子事件“忽略”(非)委托事件的事件处理程序?
可以找到一个jsfiddle here。
P.S。我知道另一种方法是:
if (e.target.classList.contains('new') || e.target.parentNode.classList.contains('new')) {
e.target.classList.toggle('active');
}
以及所有其他变体等,但遇到了我在上面列出的相同问题。
答案 0 :(得分:1)
我认为解决方案存在于事件冒泡的地方,但我无法找到利用它的方法。有没有办法让子事件“忽略”(非)委托事件的事件处理程序?
是事件冒泡是解决方案的一部分,利用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>
答案 1 :(得分:1)
您可以使用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');
}
});
&#13;
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;
}
&#13;
<button>Press Me!</button>
<div id="put-stuff-here">
</div>
&#13;