javascriptdom-eventsmootools

Avoid Adding Event Multiple Times


I am dynamically adding events using addEvent("keydown", function() {}); to an element. My problem is that there are times when this code gets run on the same element twice or more. The behavior becomes clunky as the function registered for that event runs a couple of times.

Is there a way for me to run the code above only once on an element? Maybe check if the event has already been added before?


Solution

  • Either don't use a new function each time, or use a class or something to tell you you've added it.

    Not using a new function each time

    MooTools' addEvent is a fairly thin wrapper on addEventListener/attachEvent, which won't add the same function twice. So if you ensure you're using the same function, you can call addEvent again without it doing anything:

    // Somewhere it's created **once**
    function keyDownHandler() {
        // ....
    }
    

    then:

    element.addEvent("keydown", keyDownHandler);    // Adds it only if not there
    

    Live Example:

    addIt();
    addIt();
    
    function addIt() {
      $("foo").addEvent("click", handler);
    }
    
    function handler() {
      var p = document.createElement('p');
      p.innerHTML = new Date();
      document.body.appendChild(p);
    }
    <div id="foo">Click me</div>
    <script src="https://ajax.googleapis.com/ajax/libs/mootools/1.5.0/mootools-yui-compressed.js"></script>

    Remembering you've added it:

    if (!element.hasClass("keydown-handler")) {
        element.addClass("keydown-handler").addEvent("keydown", function() { /*...*/});
    }
    

    Live Example:

    addIt();
    addIt();
    
    function addIt() {
      var element = $("foo");
      if (!element.hasClass("click-handler")) {
        element.addClass("click-handler").addEvent(
          "click",
          function() {
            var p = document.createElement('p');
            p.innerHTML = new Date();
            document.body.appendChild(p);
          }
        );
      }
    }
    <div id="foo">Click me</div>
    <script src="https://ajax.googleapis.com/ajax/libs/mootools/1.5.0/mootools-yui-compressed.js"></script>