Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

event listener does not work

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>
like image 859
ja. Avatar asked Dec 18 '22 13:12

ja.


2 Answers

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.

like image 163
Stefan Strigler Avatar answered Dec 21 '22 02:12

Stefan Strigler


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>
like image 28
mqsoh Avatar answered Dec 21 '22 02:12

mqsoh