如果删除用于启动事件气泡的DOM元素,或者由其子级启动事件气泡的DOM元素,如果删除该元素,它会继续气泡吗?
例如,假设您有一个表格,并且想检测表格单元格上的点击事件。另一段JS执行了AJAX请求,一旦请求完成,最终将完全替换该表。
如果我单击表格,并且在表格被成功完成的AJAX请求替换后立即发生了什么?我问是因为我看到了一些点击事件似乎没有冒泡的行为,但是很难复制。
我正在表的父元素上观看事件(而不是将事件附加到每个TD上,并且有时似乎没有达到它。
EDIT:再次遇到此问题,并最终找到根源。根本不是一个冒泡事件!请参阅下面的详细信息。
经验:这取决于您使用的浏览器; IE取消了该事件,其他所有事件(据我所知)仍在继续。请参阅下面的测试页和讨论。
理论上: Andy E's head有助于found认为DOM2 says the event should continue,因为冒泡应基于树的initial状态。因此,大多数人的行为是正确的,IE本身就在这里。让奎尔感到惊讶。
但是:这是否与您看到的内容有关,确实是另一个问题。您正在观察对表的父元素的单击,并且您怀疑的是很少有,当您单击表时,会出现带有Ajax补全的竞争条件,该条件会替换表并导致点击丢失。 Java解释器中不存在这种竞争条件,因为目前,浏览器上的Javascript是单线程的。 (不过,工作线程即将到来-哇!)但是从理论上讲,单击可能发生并由浏览器中的非Javascript UI线程排队,然后ajax可以完成并替换元素,然后排队的UI事件被处理,根本不会发生,也不会冒泡,因为元素已不再具有父元素,因此已被移除。能否实际发生将取决于浏览器的实现。如果您在任何开放源代码浏览器中看到它,则可以查看它们的源以排队UI事件以供解释器处理。但这与实际删除带有代码within事件处理程序的元素不同,如下所示。 确实冒泡持续性方面的经验结果:
UPDATE:
在测试中,IE9和IE10继续该事件,因此IE不符合规范的行为在IE8处停止。使用DOM0处理程序的测试页:<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
#log p {
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript'>
window.onload = pageInit;
function pageInit() {
var parent, child;
parent = document.getElementById('parent');
parent.onclick = parentClickDOM0;
child = document.getElementById('child');
child.onclick = childClickDOM0;
}
function parentClickDOM0(event) {
var element;
event = event || window.event;
element = event.srcElement || event.target;
log("Parent click DOM0, target id = " + element.id);
}
function childClickDOM0(event) {
log("Child click DOM0, removing");
this.parentNode.removeChild(this);
}
function go() {
}
var write = log;
function log(msg) {
var log = document.getElementById('log');
var p = document.createElement('p');
p.innerHTML = msg;
log.appendChild(p);
}
</script>
</head>
<body><div>
<div id='parent'><div id='child'>click here</div></div>
<hr>
<div id='log'></div>
</div></body>
</html>
使用attachEvent
/addEventListener
处理程序的测试页(通过原型):
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
#log p {
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js'></script>
<script type='text/javascript'>
document.observe('dom:loaded', pageInit);
function pageInit() {
var parent, child;
parent = $('parent');
parent.observe('click', parentClick);
child = $('child');
child.observe('click', childClick);
}
function parentClick(event) {
log("Parent click, target id = " + event.findElement().id);
}
function childClick(event) {
log("Child click, removing");
this.remove();
}
function go() {
}
var write = log;
function log(msg) {
$('log').appendChild(new Element('p').update(msg));
}
</script>
</head>
<body><div>
<div id='parent'><div id='child'>click here</div></div>
<hr>
<div id='log'></div>
</div></body>
</html>
target
属性外,事件与它们触发的事件没有真正的联系。当您删除元素时,传播事件的内部代码不应具有任何“意识”,即原始元素已从可见文档中移出。