DOMNodeInserted 没有按预期工作?
on DOMNodeInserted not working as expected?
基于this question,我写了如下代码:
$(function() {
$( document ).on('DOMNodeInserted',"span:contains('Suggested Post')", function() {
console.log("New Suggested Post found");
})
})
当我向下滚动页面并创建这些元素时,我没有看到我期望看到的控制台消息。但是,如果我在控制台中手动输入 $("span:contains('Suggested Post')").length
,输出会继续增加。
想法?
@Barmar 请求的片段。它的行为与我的真实场景并不完全一样,但它仍然不正确...
$(document).on('DOMNodeInserted', "div:contains('Banana')", function() {
console.log("new banana detected!");
});
$('#btn').on('click', function() {
var fruit = '';
switch (Math.floor((Math.random() * 3) + 1)) {
case 1:
fruit = 'Apple'
break;
case 2:
fruit = 'Orange'
break;
case 3:
fruit = 'Banana'
break;
default:
fruit = "WTF"
}
$('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
<strong>Banana Detector</strong>
<button id="btn" type="button">Add Banana!</button>
</div>
您需要将委托绑定到正在插入的元素的直接 parent。
这是因为 DOMNodeInserted
事件冒泡了。如果将它绑定到外部容器,它将冒泡到包含 DIV,并且由于 Banana Detector
标题,DIV 将匹配 :contains(Banana)
。即使您将其移出容器,它也会匹配,因为之前添加的节点包含 Banana
.
这就是为什么当存在实际匹配时会触发两次:它会为匹配的新元素触发一次,然后为始终匹配的容器触发一次。
我最初以为event.StopPropagation()
可以解决问题,但事实并非如此。当有实际匹配时,它将防止双发。但是当没有匹配时它仍然会触发——事件不会在新元素上触发(因为它不匹配),所以 event.stopPropagation()
不会 运行,所以它冒泡到匹配的容器。
$("#fakeDocument").on('DOMNodeInserted', "div:contains('Banana')", function() {
console.log("new banana detected!");
});
$('#btn').on('click', function() {
var fruit = '';
switch (Math.floor((Math.random() * 3) + 1)) {
case 1:
fruit = 'Apple'
break;
case 2:
fruit = 'Orange'
break;
case 3:
fruit = 'Banana'
break;
default:
fruit = "WTF"
}
$('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
<strong>Banana Detector</strong>
<button id="btn" type="button">Add Banana!</button>
</div>
基于this question,我写了如下代码:
$(function() {
$( document ).on('DOMNodeInserted',"span:contains('Suggested Post')", function() {
console.log("New Suggested Post found");
})
})
当我向下滚动页面并创建这些元素时,我没有看到我期望看到的控制台消息。但是,如果我在控制台中手动输入 $("span:contains('Suggested Post')").length
,输出会继续增加。
想法?
@Barmar 请求的片段。它的行为与我的真实场景并不完全一样,但它仍然不正确...
$(document).on('DOMNodeInserted', "div:contains('Banana')", function() {
console.log("new banana detected!");
});
$('#btn').on('click', function() {
var fruit = '';
switch (Math.floor((Math.random() * 3) + 1)) {
case 1:
fruit = 'Apple'
break;
case 2:
fruit = 'Orange'
break;
case 3:
fruit = 'Banana'
break;
default:
fruit = "WTF"
}
$('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
<strong>Banana Detector</strong>
<button id="btn" type="button">Add Banana!</button>
</div>
您需要将委托绑定到正在插入的元素的直接 parent。
这是因为 DOMNodeInserted
事件冒泡了。如果将它绑定到外部容器,它将冒泡到包含 DIV,并且由于 Banana Detector
标题,DIV 将匹配 :contains(Banana)
。即使您将其移出容器,它也会匹配,因为之前添加的节点包含 Banana
.
这就是为什么当存在实际匹配时会触发两次:它会为匹配的新元素触发一次,然后为始终匹配的容器触发一次。
我最初以为event.StopPropagation()
可以解决问题,但事实并非如此。当有实际匹配时,它将防止双发。但是当没有匹配时它仍然会触发——事件不会在新元素上触发(因为它不匹配),所以 event.stopPropagation()
不会 运行,所以它冒泡到匹配的容器。
$("#fakeDocument").on('DOMNodeInserted', "div:contains('Banana')", function() {
console.log("new banana detected!");
});
$('#btn').on('click', function() {
var fruit = '';
switch (Math.floor((Math.random() * 3) + 1)) {
case 1:
fruit = 'Apple'
break;
case 2:
fruit = 'Orange'
break;
case 3:
fruit = 'Banana'
break;
default:
fruit = "WTF"
}
$('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
<strong>Banana Detector</strong>
<button id="btn" type="button">Add Banana!</button>
</div>