删除重复的事件侦听器

时间:2017-08-16 21:21:50

标签: javascript events listener addeventlistener

我一直试图找到一种方法来删除事件监听器。我创建了一个函数,它将向一个按钮添加一个事件监听器,但如果该函数再次运行,我希望删除并再次添加该事件监听器。但是它只会添加另一个事件监听器,当我点击按钮时,它将运行两次事件监听器功能。或者即使我可以阻止它向按钮添加第二个事件监听器也会起作用。

这是代码



<button id="myId">My Button</button>
 
 
 
<script>
 
 
 
myFunction()
myFunction()
 
function myFunction() {
     var el = document.getElementById('myId')
 
     var listenerFn = function () {
          console.log('My Message')
     }
 
     el.removeEventListener('click', listenerFn)
 
     el.addEventListener('click', listenerFn)
}
 
 
 
</script>
&#13;
&#13;
&#13;

任何提示都会有所帮助。

更新:

@FathiAlqa​​dasi答案是我的问题迄今为止最好的答案。但我应该展示更多的代码。监听器功能是动态的,可以根据其功能而变化。这是我的另一个例子。

<button id="myId">My Button</button>



<script>

myFunctionA()
myFunctionA()



function myFunctionA() {
    var el = document.getElementById('myId')
    myFunctionB()
    function myFunctionB() {
        if (el.innerHTML === 'My Button') {
            var listenerFn = function () {
                console.log('My Message 1')
            }

               el.removeEventListener('click', listenerFn);

            el.addEventListener('click', listenerFn);
        }

        else {
            var listenerFn = function () {
                console.log('My Message 2')
            }

               el.removeEventListener('click', listenerFn);

            el.addEventListener('click', listenerFn);
        }
    }
}
</script>

更新2:

谢谢@代码。这是一个整洁的代码框中的代码

<button id="myId">My Button</button>

<script>
    var listenerFn;
    myFunction();
    myFunction()
    function myFunction() {
        var el = document.getElementById('myId')
        el.removeEventListener('click', listenerFn);
        listenerFn = function() {
            console.log('My Message')
        }
        el.addEventListener('click', listenerFn, false);
    }
</script>

3 个答案:

答案 0 :(得分:1)

使用事件监听器时,我喜欢将它们存储在一个对象中,以便我可以跟踪已注册的内容并在必要时轻松删除它们。

在您的情况下,将在全局范围内创建一个简单的布尔值,以检查是否需要删除侦听器。 (在添加侦听器后设置为true)。

<button id="myId">My Button</button>



<script>

var removeListener = false;

myFunction()
myFunction()

function myFunction() {
     var el = document.getElementById('myId')

     var listenerFn = function () {
          console.log('My Message')
     }

     if (removeListener) el.removeEventListener('click', listenerFn)

     el.addEventListener('click', listenerFn);
     removeListener = true;
}



</script>

<强>更新 根据您的更新,我有一个修改后的答案。我仍然不清楚你为什么要两次调用这个函数,但我们会把它作为一个给定的。

<button id="myId">My Button</button>



<script>
var listeners = {};

myFunctionA();
myFunctionA();



function myFunctionA() {
    var listenerFn1 = function() { //These functions need to be distinct so that we can refer to them when removing
        console.log('My Message 1')
    };

    var listenerFn2 = function() { //We actually didn't need to move these out from where they were, but its a little easier to read this way
        console.log('My Message 2')
    };

    function myFunctionB() {
        if (el.innerHTML === 'My Button') {
            if (listeners[el]) el.removeEventListener('click', listeners[el]);
            el.addEventListener('click', listenerFn1);
            listeners[el] = listenerFn1; //This could be expanded to account for different events, but keeping it simple for this scenario
        }
        else {
            if (listeners[el]) el.removeEventListener('click', listeners[el]);
            el.addEventListener('click', listenerFn2);
            listeners[el] = listenerFn2;
        }
    }

    var el = document.getElementById('myId');
    myFunctionB();
}
</script>

这里的要点是拥有一个对象,用于存储触发事件时调用的函数。该对象可以允许不同的事件,例如:

var listener = {};
var el = document.getElementById('myId');

...

//Check if a click listener exists for el
if (listener[el] && listener[el].click) {
  //Remove currently registered listener
  el.removeEventListener('click', listener[el].click);
}
listener[el] = listener[el] || {}; //If listener[el] does not exist, create it
listener[el].click = function() {
  //We can use an anonymous function in this case because we do not need to compare it to any other functions
  console.log('Click 1');
};
el.addEventListener('click', listener[el].click);

如果要允许将多个事件附加到侦听器,则不能使用匿名函数,因为要确保不要两次添加相同的函数。

var listener = {};
var el = document.getElementById('myId');

...

var eventHandler1 = function() {
  console.log('eventHandler1');
};
var eventHandler2 = function() {
  console.log('eventHandler2');
};
//Check if a click listener exists for el that uses eventHandler1
if (listener[el] && listener[el].click && listener[el].click.includes(eventHandler1)) {
  //Remove listener with eventHandler1
  el.removeEventListener('click', listener[el].click.filter(function(val) {
    return val === eventHandler1;
  }));
}
listener[el] = listener[el] || {}; //If listener[el] does not exist, create it
listener[el].click = listener[el].click || [];
listener[el].click.push(eventHandler1);
el.addEventListener('click', eventHandler1);

答案 1 :(得分:0)

   <button id="myId">My Button</button>



   <script>

   myFunction()
   myFunction()
   function listenerFn () {
             console.log('My Message')
        }
   function myFunction() {
        var el = document.getElementById('myId')

        el.removeEventListener('click', listenerFn)

        el.addEventListener('click', listenerFn)
   }
   </script>

答案 2 :(得分:0)

在JS中,函数是对象类型,这意味着它们是引用类型。我的意思是你每次运行myFunction;

function myFunction() {
     var el         = document.getElementById('myId'),
         listenerFn = function () {
                        console.log('My Message')
                      };

     el.removeEventListener('click', listenerFn)
     el.addEventListener('click', listenerFn)
}

你创建一个单独的listenerFn因此removeEventLister()可以区分它们,因为removeEventListener()的参数必须引用先前设置的事件监听器函数。

你应该这样做;

&#13;
&#13;
<button id="myId">My Button</button>

<script>

function listenerFn() {
  console.log('My Message')
}

function myFunction() {
   var el = document.getElementById('myId')
   el.removeEventListener('click', listenerFn)
   el.addEventListener('click', listenerFn)
}

myFunction();

</script>
&#13;
&#13;
&#13;