避免多次添加事件

新手上路,请多包涵

我正在使用 addEvent("keydown", function() {}); 向元素动态添加事件。我的问题是有时这段代码会在同一个元素上运行两次或更多次。随着为该事件注册的函数运行几次,行为变得笨拙。

有没有办法让我只在一个元素上运行一次上面的代码?也许检查之前是否已经添加了事件?

原文由 asp.patrickg 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 443
2 个回答

要么不要每次都使用新功能,要么使用类或其他东西来告诉你你已经添加了它。

不是每次都使用新功能

MooTools’ addEventaddEventListener / attachEvent 上的一个相当薄的包装器,它不会添加两次相同的功能。因此,如果您确保使用的是相同的函数,则可以再次调用 addEvent 而不执行任何操作:

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

然后:

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

现场示例:

 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>

记住你已经添加了它:

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

现场示例:

 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>

原文由 T.J. Crowder 发布,翻译遵循 CC BY-SA 3.0 许可协议

也许您的问题不是在何时何地添加事件处理程序,而是如何添加。可以将事件委托给父元素。例如,这是将事件处理程序直接添加到目标元素的经典方法。

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

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

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

当然,只有第一段有点击事件。

下面是一个事件委托的例子。

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

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

由于事件侦听器已分配给其所有子项的父项,因此无论何时何地创建,所有段落都将具有点击事件。当您动态地将元素添加到页面中时,它非常有用。

我不知道这有多大帮助,但很高兴知道。

元素.委托

原文由 Danijel 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题