我的页面上有一些嵌套的元素,它们具有相同的处理程序,只应为事件目标调用它们,而不会影响DOM树中较高的元素。为了实现此行为,我使用了stopPropagation方法,并且还可以。然后,我必须为嵌套div之外的body和其他元素添加一些处理程序,无论如何都应调用它们。当然,现在不能选择stopPropagation,但是如何使它工作呢?
这是一个示例:
的HTML:
<div id="container">
<div id="nested1" class="nested">
<div id="nested2" class="nested">
<div id="nested3" class="nested">
<div id="no-handler"></div>
</div>
</div>
</div>
</div>
CSS:
#container {
display: block;
width: 398px;
height: 398px;
padding: 30px;
border: solid 1px #888;
}
#nested1 {
width: 336px;
height: 336px;
padding: 30px;
}
#nested2 {
width: 274px;
height: 274px;
padding: 30px;
}
#nested3 {
width: 212px;
height: 212px;
padding: 30px;
}
#no-handler {
width: 150px;
height: 150px;
padding: 30px;
border: solid 1px #888;
}
.nested {
border: solid 1px #888;
}
.nested-clicked {
background-color: red;
}
.outer-clicked {
background-color: green;
}
js:
var container = document.getElementById("container");
var nested = document.getElementsByClassName("nested");
function outerHandler(e) {
this.classList.add("outer-clicked");
}
function nestedHandler(e) {
e.stopPropagation();
this.classList.add("nested-clicked");
}
container.addEventListener("click", outerHandler, false);
document.body.addEventListener("click", outerHandler, false);
for (var i = 0; i < nested.length; i++) {
nested[i].addEventListener("click", nestedHandler, false);
}
jsfiddle链接:
http://jsfiddle.net/6kgnu7fr/
单击
.nested
应将红色背景色添加到所单击的元素,并将绿色添加至外部body
和#container
UPD:
http://jsfiddle.net/6kgnu7fr/2/
单击
#no-event
或.nested
内的任何其他元素也应为此.nested
元素调用nestedHandler。 最佳答案
您可以在target
中检查事件的nestedHandler
,而不是停止传播。仅当目标是class
时才更改this
,以便仅将事件应用于发生事件的div
:
function nestedHandler(e) {
if (e.target === this) {
this.classList.add("nested-clicked");
}
}
编辑
完成编辑后,这将变得更加困难。这样做的方法是找到
e.target
具有“嵌套”类的第一个祖先,然后用它而不是target
进行比较:function findAncestorWithClass(dom, targetClass){
if(!dom){
return; // (undefined)
}
if(dom.classList.contains(targetClass)){
return dom;
}
// terminal recursion
return findAncestorWithClass(dom.parentNode, targetClass);
}
这是幼稚的镜头。您可能需要寻找一种提高效率的方法,例如通过避免在每个
.nested
div上查找第一个祖先。请参阅下面的工作片段。
var container = document.getElementById("container");
var nested = document.getElementsByClassName("nested");
function outerHandler(e) {
this.classList.add("outer-clicked");
}
function findAncestorWithClass(dom, targetClass){
if(!dom){
return; // (undefined)
}
if(dom.classList.contains(targetClass)){
return dom;
}
// terminal recursion
return findAncestorWithClass(dom.parentNode, targetClass);
}
function nestedHandler(e) {
var nestedParent = findAncestorWithClass(e.target, "nested");
if (this === nestedParent) {
nestedParent.classList.add("nested-clicked");
}
}
container.addEventListener("click", outerHandler, false);
document.body.addEventListener("click", outerHandler, false);
for (var i = 0; i < nested.length; i++) {
nested[i].addEventListener("click", nestedHandler, false);
}
#container {
display: block;
width: 398px;
height: 398px;
padding: 30px;
border: solid 1px #888;
}
#nested1 {
width: 336px;
height: 336px;
padding: 30px;
}
#nested2 {
width: 274px;
height: 274px;
padding: 30px;
}
#nested3 {
width: 212px;
height: 212px;
padding: 30px;
}
#sub-nested {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.nested {
border: solid 1px #888;
}
.nested-clicked {
background-color: red;
}
.outer-clicked {
background-color: green;
}
<div id="container">
<div id="nested1" class="nested">
<div id="nested2" class="nested">
<div id="nested3" class="nested">
<div id="sub-nested"></div>
</div>
</div>
</div>
</div>
关于javascript - 继续传播,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33298114/