自定义事件的传播
Propagation of custom events
我希望我的 CustomEvent 从文档传播到所有 DOM 元素。
由于某种原因,它不会发生。我做错了什么?
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
你必须在你想要事件 'triggered' 的元素上发送事件。然后它将向下传播并备份 DOM
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
myDiv.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
fiddle: https://jsfiddle.net/yrf9cvr3/
传播的工作原理:事件从 document
开始,一直向下传播到它被分派到的元素(您可以使用 onCapture
标志捕获以这种方式进行的事件)。然后回到 document
。因为您是在 document
上调度,所以事件实际上并没有去任何地方,只有 document
看到了事件。
试试这个。使用 document.querySelector 并指定要跟踪的事件。单击按钮或在文本框中键入一些文本
<html>
<script>
function onLoad() {
// var myDiv = document.getElementById("myDiv");
// myDiv.addEventListener("myEvent",function(){alert("Yes!");});
// document.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
var myDiv = document.querySelector("#myDiv");
myDiv.addEventListener("click", myEventHandler, false);
myDiv.addEventListener("change", myEventHandler, false);
}
function myEventHandler(e)
{
alert('Element was '+e.target.id+'\nEvent was '+e.type);
}
</script>
<body onload="onLoad()">
<div id="myDiv">
<input type="button" id= "Button 1" value="Button 1"><br>
<input type="text" id="Text 2">
</div>
</body>
</html>
走极端。事件向下传播到它们被分派的元素并备份...所以为了在任何和基本上所有元素上触发事件(因为不知道哪些元素需要事件)你可以找到 "ends" DOM 的所有 "branches" 并向它们发送事件。
jQuery方便select结束分支
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent", function() {
alert("Yes!");
});
$(':not(:has(*))').each(function(i, el){
el.dispatchEvent(new CustomEvent("myEvent", {
detail: null,
bubbles: true
}));
});
}
https://jsfiddle.net/dkqagnph/1/
使用这将确保每个 DOM 元素(附加到正文)获得事件(假设没有元素停止传播本身),因此不需要知道哪些元素正在监听或关心事件。这不会分派到每个单独的元素,因为那样会有点矫枉过正,但只是结束并让冒泡完成它的事情。
注意:具有多个子元素的元素将多次获得该事件。您可能希望有一种方法来确保您的代码 运行 不止一次,或者不关心它是否 运行 不止一次。
我发布的是一些解决方案,并不是真正的答案。
这会将自定义事件传播到 DOM.
中的所有元素
<html>
<script>
document.dispatchCustomEvent = function(event) {
function visit(elem,event) {
elem.dispatchEvent(event);
var child = elem.firstChild;
while(child) {
if(child.nodeType==1) visit(child,event);
child = child.nextSibling;
}
}
visit(document.documentElement,event);
}
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchCustomEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
默认情况下,自定义事件不会冒泡。
原因是,自定义事件定义说:
let event = new CustomEvent(type,[options]).
选项有一个标志:bubbles,即false 默认情况下,我们必须启用它。
以下将修复您的代码
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchEvent(new CustomEvent("myEvent",{detail:null,bubbles:true}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
我希望我的 CustomEvent 从文档传播到所有 DOM 元素。 由于某种原因,它不会发生。我做错了什么?
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
你必须在你想要事件 'triggered' 的元素上发送事件。然后它将向下传播并备份 DOM
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
myDiv.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
fiddle: https://jsfiddle.net/yrf9cvr3/
传播的工作原理:事件从 document
开始,一直向下传播到它被分派到的元素(您可以使用 onCapture
标志捕获以这种方式进行的事件)。然后回到 document
。因为您是在 document
上调度,所以事件实际上并没有去任何地方,只有 document
看到了事件。
试试这个。使用 document.querySelector 并指定要跟踪的事件。单击按钮或在文本框中键入一些文本
<html>
<script>
function onLoad() {
// var myDiv = document.getElementById("myDiv");
// myDiv.addEventListener("myEvent",function(){alert("Yes!");});
// document.dispatchEvent(new CustomEvent("myEvent",{detail:null}));
var myDiv = document.querySelector("#myDiv");
myDiv.addEventListener("click", myEventHandler, false);
myDiv.addEventListener("change", myEventHandler, false);
}
function myEventHandler(e)
{
alert('Element was '+e.target.id+'\nEvent was '+e.type);
}
</script>
<body onload="onLoad()">
<div id="myDiv">
<input type="button" id= "Button 1" value="Button 1"><br>
<input type="text" id="Text 2">
</div>
</body>
</html>
走极端。事件向下传播到它们被分派的元素并备份...所以为了在任何和基本上所有元素上触发事件(因为不知道哪些元素需要事件)你可以找到 "ends" DOM 的所有 "branches" 并向它们发送事件。
jQuery方便select结束分支
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent", function() {
alert("Yes!");
});
$(':not(:has(*))').each(function(i, el){
el.dispatchEvent(new CustomEvent("myEvent", {
detail: null,
bubbles: true
}));
});
}
https://jsfiddle.net/dkqagnph/1/
使用这将确保每个 DOM 元素(附加到正文)获得事件(假设没有元素停止传播本身),因此不需要知道哪些元素正在监听或关心事件。这不会分派到每个单独的元素,因为那样会有点矫枉过正,但只是结束并让冒泡完成它的事情。
注意:具有多个子元素的元素将多次获得该事件。您可能希望有一种方法来确保您的代码 运行 不止一次,或者不关心它是否 运行 不止一次。
我发布的是一些解决方案,并不是真正的答案。 这会将自定义事件传播到 DOM.
中的所有元素<html>
<script>
document.dispatchCustomEvent = function(event) {
function visit(elem,event) {
elem.dispatchEvent(event);
var child = elem.firstChild;
while(child) {
if(child.nodeType==1) visit(child,event);
child = child.nextSibling;
}
}
visit(document.documentElement,event);
}
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchCustomEvent(new CustomEvent("myEvent",{detail:null}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>
默认情况下,自定义事件不会冒泡。
原因是,自定义事件定义说:
let event = new CustomEvent(type,[options]).
选项有一个标志:bubbles,即false 默认情况下,我们必须启用它。
以下将修复您的代码
<html>
<script>
function onLoad() {
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("myEvent",function(){alert("Yes!");});
document.dispatchEvent(new CustomEvent("myEvent",{detail:null,bubbles:true}));
}
</script>
<body onload="onLoad()">
<div id="myDiv"></div>
</body>
</html>