0

I would like the specified function to be called only if the correct button is clicked on.

function callback(func){
func();
}

The main function(s) and their results:

Attempt A:

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

Result: Opening the page and clicking any of the buttons will run function1

Attempt B:

document.addEventListener('click', function () {

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

Result: Clicking anywhere on the page will run function1

Attempt C:

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

Result: Opening the page and clicking on the buttons will run function1 and reload the page

Attempt D:

document.addEventListener('click', function () {

//The first ID doesn't exist
document.getElementById('imaginaryNum1').addEventListener('click', callback(function1));
document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

Result: Clicking anywhere on the page will run function1

Attempt E:

//The first ID doesn't exist
document.getElementById('imaginaryNum1').addEventListener('click', callback(function1));
document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

Result: Opening the page and clicking on the buttons will run function1 and reload the page

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
cateye
  • 47
  • 1
  • 9

2 Answers2

5

Sure, why wouldn't it be. Looking at your code, though, you might be better of delegating the event: it's not that hard. Basically, listen for the event you need on a level in the dom that contains each of the individual elements, and write your handler in such a way that you check if the element that fired the event is of interest, if so: handle the event, if not, just return.
You're also missing the third argument, that addEventListener expects: a boolean, indicating weather you want to handle the event during the capturing phase, or the bubbling phase, read a couple of articles on quirksmode, in particular on the distinct phases

I've also noticed that you're doing weird things with your handler function, you're going to have some issues with that. Basically, what addEventListener expects as a second argument is a reference to a function, you're passing the return value of a function (which is undefined in your case).

function clickHandler(e)//accept event argument
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (!target.id.match(/num[0-9]/))
    {//the clicked element doesn't have num1, num2, num3... as id, no need to handle this event
        return e;
    }
    //handle event. target is a reference to the clicked element
}
document.body.addEventListener('click',clickHandler,false);//<-- just the function name, no parentheses

That's all you need, one listener that'll handle all click events.

Here are a couple of JS questions that I've posted that deal with event delegation, take a look at the code, read the articles I linked to, you'll soon work it out.
delegating the change event in IE -- tricky
avoid mem-leaks in IE<9 with onload listener: my answer to the question
Augmenting the event prototype in IE<9 using delegation

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • OK. So I added the above by I got: Uncaught TypeError: Cannot call method 'addEventListener' of null nonExtension05.html:120 (anonymous function) – cateye Oct 30 '12 at 16:05
  • 1
    did you define a function called `clickHandler` - and did you make sure that the DOM was loaded when this code ran? if not: add the function with the correct name, and use one of the load-listeners of the questions I linked. Also: `addEventListener` isn't supported by IE<9, you'll have to rely on `attachEvent` if you're testing in that browser. – Elias Van Ootegem Oct 30 '12 at 16:10
  • Thanks so much for pointing me in the right direction. Partial to this article though: http://davidwalsh.name/event-delegate. :) – cateye Oct 30 '12 at 17:23
3

callback immediately executes the function that is passed into it - so it is never passed to the addEventListener - instead, undefined is passed.

.addEventListener('someEvent', callback(functionN), false) is essentially .addEventListener('someEvent', (function(){ functionN() })(), false).

Change to .addEventListener('someEvent', functionN, false) and see what happens - if you are still getting errors take a look in the Script Panel of your web browser and see what errors are being generated.

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293