Avoid Adding Event Multiple Times

狂风中的少年 提交于 2019-12-01 01:30:45

问题


I am dynamically adding events using addEvent("keydown", function() {}); to an element. My problem is that there are times when this code get's 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 only run the code above only once on an element? Maybe check if the event has already been added before?

Thanks to everyone who helps.


回答1:


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>



回答2:


Maybe your problem is not where or when to add event handler, but how to add. It is possible to delegate events to parent element. For example, this is a classic way of adding an event handler directly to the target element.

new Element( 'p', { 'text': 'Some Text' } ).inject( $( 'container' ) );

$$( '#container p' ).addEvent( 'click', function() {
    console.log( this );            
});

new Element( 'p', { 'text': 'Some Text' } ).inject( $( 'container' ) );

And, of course, only the first paragraph has click event.

And below is an example of event delegation.

$( 'container' ).addEvent( 'click:relay(p)', function() {
    console.log( this );            
});             

$( 'container' ).adopt([
    new Element( 'p', { 'text': 'Some Text' } ),
    new Element( 'p', { 'text': 'Some Text' } )
]); 

Since event listener is assigned to a parent for all of its children, all paragraphs will have the click event, no matter when and where they are created. It is very useful when you are adding elements into the page dynamically.

I do not know how much this helps, but it's good to know.

Element.Delegation



来源:https://stackoverflow.com/questions/30255311/avoid-adding-event-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!