warnerque
warnerque

Reputation: 83

Writing multiple event listeners for different buttons in Javascript

I'm trying to run two buttons to show two pop-ups. I don't understand why CODE A below doesn't work but CODE B works. When I press the "press1" button on CODE A, nothing happens. Must I output all my HTML together at once? I'm trying to run a for-loop so how could I output both working buttons?

CODE A

document.getElementById("buttondiv").innerHTML += '<tr><td><button class="press1">Press Me</button></td></tr>';

//Find all buttons on the page with the name transferToken
var button1 = document.querySelector('button.press1');

button1.addEventListener('click', function () {
  alert("Hello John");
});

document.getElementById("buttondiv").innerHTML += '<tr><td><button class="press2">Press Me</button></td></tr>';

var button2 = document.querySelector('button.press2');

button2.addEventListener('click', function () {        
  alert("Hello Jane");
});

CODE B

document.getElementById("buttondiv").innerHTML += '<tr><td><button class="press1">Press Me</button></td></tr>';

document.getElementById("buttondiv").innerHTML += '<tr><td><button class="press2">Press Me</button></td></tr>';

var button1 = document.querySelector('button.press1');

button1.addEventListener('click', function () {
  alert("Hello John");              
});

var button2 = document.querySelector('button.press2');

button2.addEventListener('click', function () {
  alert("Hello Jane");
});

Upvotes: 1

Views: 221

Answers (3)

Ashish Kumar
Ashish Kumar

Reputation: 407

The problem with CODE A is, you have button "press1" and an event listener on it but once you take that element away and re-append it, you essentially delete the bound OnClick Event because the dom is re-constructed and it won’t re-bind.

Upvotes: 0

SparK
SparK

Reputation: 5211

When you add an element via innerHTML you are making the browser redraw all the content, read the code again and parse it to rebuild the DOM, which creates a new button1 without any listener attached (the old one got destroyed).

You should first createElement to make your new button and then appendChild to your buttondiv.

So you preserve old objects inside your buttondiv and their events. The advantage is that you don't force the browser to parse HTML and only deal with objects in memory instead, which is way faster.

Upvotes: 2

Mamun
Mamun

Reputation: 68933

Setting the value of innerHTML removes all of the element's descendants and replaces them with nodes constructed by parsing the HTML given in the string htmlString.

innerHTML completely destroy and recreate element, thus forget all the prevously attached event.

To insert the HTML into the document rather than replace the contents of an element, use the method insertAdjacentHTML().

Demo:

document.getElementById("buttondiv").insertAdjacentHTML('beforeend', '<tr><td><button class="press1">Press Me</button></td></tr>');
//Find all buttons on the page with the name transferToken
var button1 = document.querySelector('button.press1');
button1.addEventListener('click', function () {
  alert("Hello John");
});
document.getElementById("buttondiv").insertAdjacentHTML('beforeend','<tr><td><button class="press2">Press Me</button></td></tr>');
var button2 = document.querySelector('button.press2');
button2.addEventListener('click', function () {
  alert("Hello Jane");
});
<div id="buttondiv"></div>

Upvotes: 1

Related Questions