Skip to content Skip to sidebar Skip to footer

Rebind Javascript Events And Addeventlistener Fires Twice

I have a class method which defines the event listeners. Let us use the following code snippet for simplicity. Everything works fine when using bindEvents() only once, however for

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); 
}

removeEventListener docs

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"