Any ideas why this does not work.
The Yes button when clicked works once - the No button does not work
function $(x) {
return document.getElementById(x);
}
var glob = 0;
function new_index() {
glob += 1;
return "d" + glob;
}
function play() {
say("Hello is JS Fun?");
response("No",
function() {
say("Oh dear")
});
response("Yes",
function() {
say("Great:");
});
}
function say(x) {
$("txt").innerHTML += x;
}
function response(Txt, Fun) {
var n = new_index();
var s = "<button id='" + n + "'>" + Txt + "</button>";
say(s);
var xx = $(n);
// xx.onclick=Fun;
xx.addEventListener("click", Fun);
}
play();
<div id="txt"></div>
It's because every time you set the innerHTML it doesn't just add as you might think, it sets innerHTML to a new value and by that deleting the old elements with the old event listeners attached.
As others have mentioned, the main issue in your code is that you lose event bindings on subsequent innerHTML
calls -- No stops working because it comes after Yes. When Yes appends text it breaks itself.
When working with the DOM, it's better to create elements than alter HTML text (with innerHTML
). In the case of your buttons it means you don't have to (1) create a button with an ID and then (2) find the button. With createElement
you have a reference to it.
function $(x) {
return document.getElementById(x);
}
var glob = 0;
function new_index() {
glob += 1;
return "d" + glob;
}
function play() {
say(text("Hello is JS Fun?"));
response("No",
function() {
say(text("Oh dear"));
});
response("Yes",
function() {
say(text("Great:"));
});
}
function text(String) {
var node = document.createElement("span");
node.innerHTML = String;
return node;
}
function say(x) {
$("content").appendChild(x);
}
function response(Txt, Fun) {
var button = document.createElement("button");
button.innerHTML = Txt;
button.addEventListener("click", Fun);
say(button);
}
play();
<div id="content"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With