Search code examples
javascripteventsstoppropagation

How to stop event propagation when eventListener attached to same elements in IE 8?


How can I stop executing other event handlers with pure javascript in case if they are attached to same element in IE8?

I can stop event propagation with Event.stopImmediatePropagation method, but it's not supported by IE8.

// document.getElementById('my-elem').attachEvent('click', firstHandler); 
document.getElementById('my-elem').addEventListener('click', firstHandler);
// document.getElementById('my-elem').attachEvent('click', secondHandler); 
document.getElementById('my-elem').addEventListener('click', secondHandler);


function firstHandler(ev){
  ev.stopPropagation();
  alert('1');
}

function secondHandler(ev){
  ev.stopPropagation();
  alert('2');
}
<div id="my-elem">
  How to stop propagation ?
</div>


Solution

  • A very simplified (and probably error prone) polyfill/shim. Capture the original attachEvent/detachEvent methods, and create new ones that will check a flag.

    Also it will only prevent events that were attached before the one calling stopImmediatePropagation.

    if (!Event.prototype.stopImmediatePropagation) {
      (function() {
        var attachEvent = Element.prototype.attachEvent,
            detachEvent = Element.prototype.detachEvent;
    
        Element.prototype.attachEvent = function(type, callback) {
          attachEvent.call(this, "on"+type, function(event) {
            if (!event.immediatePropagationStopped) {
              callback(event);
            }
          });
        };
    
        Element.prototype.detachEvent = function(type, callback) {
          detachEvent.call(this, type, callback);
        };
      }());
    
      Event.prototype.stopImmediatePropagation = function() {
        this.immediatePropagationStopped = true;
      };
    }
    
    document.getElementById("test").attachEvent("click",function(e){
      console.log("hi");
    });
    document.getElementById("test").attachEvent("click",function(e){
      e.stopImmediatePropagation();
      console.log("hi2");
    });
    document.getElementById("test").attachEvent("click",function(e){
      console.log("hi3");
    });
    <div id="test">Click me</div>

    While this did work in the IE 8 emulation mode in my IE 11 browser, as I mentioned earlier this is simplified. So it doesn't do much error checking and other needed checks. Find a proper polyfill for add/removeEventListener, preventDefault, stopPropagation, stopImmediatePropagation if you want production usable code.

    Modernizr lists ES5 DOM SHIM as having a polyfill for stopImmediatePropagation so it might have polyfills for the others