【问题标题】:Removing event listeners on automatically created multiple elements删除自动创建的多个元素上的事件侦听器
【发布时间】:2012-04-06 09:33:55
【问题描述】:

我试图在元素被点击后从元素中删除事件监听器,虽然我似乎有一个可行的解决方案,但这并不理想,我不确定为什么它与损坏的代码不同。

虽然我意识到有更简单的方法可以做到这一点,但这取自我正在研究的一个 JS 类,因此需要保留一些结构。

这与我之前发表的一篇文章有​​关,该文章得到了正确回答(但在我扩展示例时不起作用)-Removing event listeners with anonymous function calls in JavaScript

在此示例中,最后创建的 div 正确删除了侦听器,但较早的未正确删除(此处为小提琴 - http://jsfiddle.net/richwilliamsuk/NEmbd/):

var ctnr = document.getElementById('ctnr');
var listener = null;

function removeDiv (d) {
    alert('testing');
    d.removeEventListener('click', listener, false);
}

function addDiv () {
    var div = document.createElement('div');
    div.innerHTML = 'test';
    ctnr.appendChild(div);
    div.addEventListener('click', (function (d) { return listener = function () { removeDiv(d); } })(div), false);
}

addDiv();
addDiv();
addDiv();

在我开始工作的版本中,我创建了一个包含所有侦听器的数组(此处为小提琴 - http://jsfiddle.net/richwilliamsuk/3zZRj/):

var ctnr = document.getElementById('ctnr');
var listeners = [];

function removeDiv(d) {
    alert('testing');
    d.removeEventListener('click', listeners[d.id], false);
}

function addDiv() {
    var div = document.createElement('div');
    div.innerHTML = 'test';
    ctnr.appendChild(div);
    div.id = listeners.length;
    div.addEventListener('click', (function(d) {
        return listeners[listeners.length] = function() {
            removeDiv(d);
        }
    })(div), false);
}


addDiv();
addDiv();
addDiv();

document.getElementById('btn').addEventListener('click', function() {
    alert(listeners);
}, false);​

最后一个工作正常,但我确信侦听器数组不是必需的。可能是我太担心了,但我想知道最佳解决方案。

【问题讨论】:

    标签: javascript event-handling dom-events event-listener


    【解决方案1】:

    你是对的,你不需要一个数组,只需将每个监听器保存在一个变量中,而不是在你的 remove() 函数中传递 eventlistener,

    var ctnr = document.getElementById('ctnr');
    
    function removeDiv(d, ev) {
        alert('testing');
        d.removeEventListener('click', ev, false);
    }
    
    function addDiv() {
        var div = document.createElement('div');
        div.innerHTML = 'test';
        ctnr.appendChild(div);
        div.addEventListener('click', (function(d) {
            var myfunc;
            return myfunc = function() {
                removeDiv(d, myfunc);
            }
        })(div), false);
    }
    
    
    addDiv();
    addDiv();
    addDiv();
    
    document.getElementById('btn').addEventListener('click', function() {
        alert(listeners);
    }, false);​​
    

    updated jsfiddle page

    【讨论】:

      【解决方案2】:

      如果每个监听器不相等,你必须保存它们,所以你需要监听器和元素之间的关系。由于元素由对象(DOM:文档对象模型)表示,因此您可以向它们添加自定义属性(尽管不推荐:Can I add arbitrary properties to DOM objects?)(demo):

      var ctnr = document.getElementById('ctnr');
      
      function removeDiv (d) {
          alert('testing');
          d.removeEventListener('click', d.custom_Listener , false);
      }
      
      function addDiv () {
          var div = document.createElement('div');
          div.innerHTML = 'test';
          div.custom_Listener = function(){removeDiv(this)};
          ctnr.appendChild(div);
          div.addEventListener('click', div.custom_Listener , false);
      }
      

      但是由于您在每个 div 中使用相同的侦听器,最好不要为每个 div 使用单独的函数,而是使用相同的函数 (demo):

      var ctnr = document.getElementById('ctnr');
      var listener = function(){
          removeDiv(this);
      };
      
      function removeDiv (d) {
          alert('testing');
          d.style.backgroundColor = '#36f';
          d.removeEventListener('click', listener, false);
      }
      
      function addDiv () {
          var div = document.createElement('div');
          div.innerHTML = 'test';
          ctnr.appendChild(div);
          div.addEventListener('click', listener , false);
      }
      

      【讨论】:

      • 对不起,看看我的问题,我真的应该把它放回面向对象的上下文中(侦听器在闭包内的原因)。这可行,但不能应用于我的班级(我的错是没有正确显示所有内容)。不过谢谢 - 将编辑问题!
      猜你喜欢
      • 2022-11-24
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 2011-08-27
      相关资源
      最近更新 更多