事件监听器不起作用。

4

有没有想法,为什么这个不起作用。

当点击Yes按钮时,它能够工作一次 - No按钮不能工作

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>


这个问题无法解决。您能否请解释一下您的代码预期执行什么操作,以及实际执行了什么操作? - Teemu
3个回答

8

这是因为每次设置innerHTML时,它不仅仅是像您可能想的那样添加元素,它会将innerHTML设置为一个新值,并删除旧的带有事件监听器的元素。


3
Goodness inerHTML += x 不是一个纯添加操作,而是具有副作用!哇,接下来会发生什么。 - ja.
这是因为innerHTML是DOM的序列化。因此,它将DOM转换为字符串,创建一个新的更长的字符串,然后将该字符串反序列化为新的DOM。 - JoshRagem

2
如其他人所提到的,您代码中的主要问题是在随后的innerHTML调用中丢失了事件绑定 -- No停止工作是因为它在Yes之后。当Yes添加文本时,它会破坏自身。
在使用DOM时,最好创建元素而不是修改HTML文本(使用innerHTML)。对于您的按钮,这意味着您不必(1)创建具有ID的按钮,然后(2)查找该按钮。使用createElement,您可以引用它。

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>


1
事件处理程序在 $("txt").innerHTML += x; 上丢失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接