Propagation of custom events

4.9k views Asked by At

I expect my CustomEvent to be propagated from document to all the DOM elements. For some reason, it does not happen. What am I doing wrong?

<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>
4

There are 4 answers

3
Sai Varun On BEST ANSWER

By default Custom Events are not bubbled.

Reason being, Custom Event definition says:

let event = new CustomEvent(type,[,options]).

Options have a flag : bubbles, which is false by default, we have to enable it.

Following will fix your code

<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>

0
Claus On

Try this one. Use document.querySelector and specify the events you want to track. Click the button or type some text in the text box

 <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>

0
Rediska On

I am posting some solution, not really an answer. This will propagate a custom event to all the elements in the 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>
0
jking On

This is currently not possible as stated in the MDN doc https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events#event_bubbling, event can only bubble from child to ancestors, i.e. upward for now.

The best way you can achieve this is use document.querySelector to target the element(s) you want to dispatch the event to, then dispatch as needed.

document.querySelector("#myDiv").dispatchEvent(customEv);