Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kaaes/1130943 to your computer and use it in GitHub Desktop.
Save kaaes/1130943 to your computer and use it in GitHub Desktop.
Binding the same event listeners more than once
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Binding the same event listeners more than once</title>
</head>
<body>
<p>As it appears, attaching the same callback for event more that once is not that easy.</p>
<p>Passing the reference to the function more than once has no effect. It has to be different function each time the listener is created.</p>
<p>It should be good news meaning it isn't so easy to kill the app with accidental recursive binding of events.</p>
<p>Yet, somehow I manage to achieve it in YUI from time to time without putting any effort.</p>
<ul>
<li class="clickable" tabindex="1">element 1</li>
<li class="clickable" tabindex="2">element 2</li>
<li class="clickable" tabindex="3">element 3</li>
<li class="clickable" tabindex="4">element 4</li>
</ul>
<script type="text/javascript">
var clickables = document.getElementsByClassName('clickable');
function clickInteraction(evt) {
evt.target.addEventListener('click', clickInteraction, false);
console.log('Fired! ' + evt.type + ' ' + this.nodeName)
}
/*
* If we use reference to the function event will bind only once
* even if I try to make it attach recursively in clickInteraction
*/
clickables[0].addEventListener('click', clickInteraction, false);
/*
* If clickInteraction is called from anonymous function
* event will be bound twice - the recursion stops in
* clickInteraction as it uses reference to itself
*/
clickables[1].addEventListener('click', function(evt) { clickInteraction.call(this, evt) }, false);
/*
* This is brutal forcing of recursive click event listeners
* by creating local function inside every click callback.
* This works as I expected - every click causes additional listener
* to be added
*/
clickables[2].addEventListener('click', function(evt) {
(function clickInteraction(evt) {
evt.target.addEventListener('click', clickInteraction, false);
console.log('Fired! ' + evt.type + ' ' + this.nodeName)
}).call(this, evt)
}, false);
/*
* Just to compare with previous one - this works only
* if local function shadows the global one - here recursion also
* stops after second listener
*/
clickables[3].addEventListener('click', function(evt) {
(function(evt) {
evt.target.addEventListener('click', clickInteraction, false);
console.log('Fired! ' + evt.type + ' ' + this.nodeName)
}).call(this, evt)
}, false);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment