Rebind Javascript Events And Addeventlistener Fires Twice
Solution 1:
The .addEventListener method ensures that the same function reference won't be bound more than once to the same element/event/captures combination.
In your case, each time you execute bindEvents()
a completely new handler is passed to the click
event listener since you define new function (no matter it looks the same, it is different object). To use the same handler each time you must define it outside bindEvents
and pass it by name (by reference). This works as expexted:
functionclickHandler(e){
alert('clicked!');
}
functionbindEvents() {
document.querySelector('button').addEventListener('click', clickHandler);
}
// Initial event bindingbindEvents();
// Rebind events at some point for dynamically created elementsbindEvents();
<button>click</button>
However with jQuery I use the following approach which allows me to specify that only elements in a specific container (context or ctx) will be bound:
$.fn.bindEvents = functionbindEvents(ctx){
ctx = ctx || this;
$('button', ctx).on('click', function(event){
alert(1);
});
};
$('body').bindEvents();
$('div').bindEvents();
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><button>Click</button><div><button>in div </button></div>
In the example above bindEvents
is executed twice but the first button is bound only once since it's not in a div. While if you click on the second button it alerts twice because satisfies both contexts.
Solution 2:
addEventListener
does not overwrite existing event listeners, it simply adds a new one as the method name implies. Existing listeners must be removed using the removeEventListener
method.
functiononClick($event) {
console.log('clicked!');
}
functionbindEvents() {
/** Remove event listener first **/document.querySelector('button').removeEventListener('click', onClick);
document.querySelector('button').addEventListener('click', onClick);
}
Solution 3:
Apart from removeEventListener
, You can also use Event delegation. Using this mechanism event is handler by attaching event listener to parent element.
var elem = document.querySelector('div');
elem.addEventListener('click', function(e) {
e = e || event
var target = e.target;
if (target.nodeName != 'BUTTON')
return;
console.log('clicked ' + target.textContent);
});
//Simulate addition of dynamic elementssetTimeout(function() {
var newButton = document.createElement('button');
newButton.innerHTML = 'Click 2';
elem.appendChild(newButton)
}, 2000)
<div><buttontype="button">Click</button></div>
Post a Comment for "Rebind Javascript Events And Addeventlistener Fires Twice"