How to get click id with addEventListener medthod

I tried to modify this snippet of code found on stackoverflow for different purposes unsuccessful:


<button id="1" onClick="reply_click(this.id)">B1</button>
<button id="2" onClick="reply_click(this.id)">B2</button>
<button id="3" onClick="reply_click(this.id)">B3</button>

<script type="text/javascript">
function reply_click(clicked_id)
{
    alert(clicked_id);
}
</script>

The code works great. However, I want to better control my function like something below:


var button1 = document.getElementById('1')
  , button2 = document.getElementById('2')
  , button3 = document.getElementById('3')
  ;

function reply_click(clicked_id)
{
    console.log(clicked_id);
}

button1.addEventListener("click", reply_click('1'), false);
button2.addEventListener("click", reply_click('2'), false);
button3.addEventListener("click", reply_click('3'), false);

And the console.log on Chrome saying:


Uncaught TypeError: Cannot call method 'addEventListener' of null

How to make this possible?

Thank you.

function reply_click(event) {
  console.log(event.target.id);
}

button1.addEventListener('click', reply_click, false)

When you write ‘(…)’ after a function, js immediately executes the function and replaces the function call with the return value of the function. However, you don’t want the click function to execute until after a user clicks on the button. To do that, you supply just the function name, and then js will add the ‘(…)’ when someone clicks on the button.

Now, you might wonder about this:

<button id="3" onClick="reply_click(this.id)">B3</button>

You might be thinking, doesn’t that function execute immediately too since it has ‘(…)’ after the function name. The answer is no. When you specify an event handler ‘inline’ in the html, js actually does this to the function you specify:

onclick = function() { reply_click(this.id) }

That thing on the right of the equals sign is called an ‘anonymous function’, and as you can see there is no ‘(…)’ after the function, so it does not execute immediately.

Note that the anonymous function does not return anything. Even though reply_click may return something, the anonymous function does not return something. For example, suppose reply_click returns false in order to cancel the click. That means when someone clicks on the button, the anonymous function executes, and because all function calls are replaced by their return values, that means reply_click(this.id) will replaced by false, giving you:

function() { false }

And because the anonymous function does not say ‘return’ anywhere, the false value does not get returned. That’s why you will see this a lot:

<button id="3" onClick="return reply_click(this.id)">B3</button>

js translates that to:

onclick = function() { return reply_click(this.id) }

Then if reply_click(this.id) returns false when it executes, you get:

function () { return false };

Thank you,

It works like a charm.

And thanks for the lengthy explanation.

Hello,

Please help me again.
I’ve another problem. I used to initialize a fake click from another function with the simple code below:


reply_click('1');

Now it’s not working. I’ve no idea why???

  1. Post the definition of reply_click().

  2. Describe what you expect to happen, and describe what actually happens, i.e. NEVER just say “It’s not working”.

Well,

I’m kind of extremely stupid. Just use


button1.click();

It takes me a full day to solve though.

See the simple code below and you’ll fully understand what I’m attempting to do. Hope this help struggling people too. Thanks million time for your help.


var log = function(msg) {
	document.getElementById('log').innerHTML = msg + "<br/>";
};

var button1 = document.getElementById('button1')
  , button2 = document.getElementById('button2')
  , button3 = document.getElementById('button3')
  ;

function switchResources(event) {
	switch(event.target.id) {
		case 'button1':
			content = 'Button 1 clicked.';
			displayLog();
			break;
		case 'button2':
			content = 'Button 2 clicked.';
			displayLog();
			break;
		case 'button3':
			content = 'Button 3 clicked.';
			displayLog();
			break;
	}
}

function displayLog(evt) {
	log(content);
}

(function() {
	setTimeout(function(){
		button2.click();
	}, 5000);
})();

button1.addEventListener("click", switchResources, false);
button2.addEventListener("click", switchResources, false);
button3.addEventListener("click", switchResources, false);

It’s considered bad form to set/retrieve global variables from within functions. Instead, you should send any data that a function needs as an argument. For example,


function switchResources(event) {
	var id = event.target.id;
        var button_number = id.slice(-1);
        displayLog("Button " + button_number + " clicked.");
}


function displayLog(msg) {
	log(msg);
}

@7stud

You are a genius. You’ve helped me again. That’s down 16 lines of code to just a mere 5 lines.
What is the keyword do you suggest I can do research about this topic.
All the codes I wrote in the past always set and retrieve as global variables, because I have to use them across functions.

Now I understand why my scripts are not efficient.
Thank you

What is the keyword do you suggest I can do research about this topic.

Which topic? Global variables? Search google for ‘why are global variables bad’.

About passing local arguments across functions. I find this thing is particularly difficult.

Do you think using prototype property make any better?

About passing local arguments across functions. I find this thing is particularly difficult.

How so? Do you know some other language that doesn’t seem to correspond with the way js works?

Sound like there’s an answer for me on Google, or Yahoo, perhaps. :slight_smile: