【问题标题】:Event listeners not working with dynamically created buttons, using pure Javascript?事件监听器不使用动态创建的按钮,使用纯 Javascript?
【发布时间】:2018-07-06 22:02:51
【问题描述】:

我在每个 li 元素之后通过 Javascript 创建按钮元素。但是,事件侦听器不适用于这些按钮。事件侦听器绑定到带有文本“Enter”的按钮,该文本已经在 HTML 中并且没有动态创建工作正常。因此,我相信这个问题与我使用 Javascript 创建按钮有关。我怀疑这可以通过事件委托来解决,但我不知道如何解决。

以下是我的 HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Javascript + DOM</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>Shopping List</h1>
    <p id="first">Get it done today</p>
    <input id="userinput" type="text" placeholder="Enter items">
    <button id="enter">Enter</button>
    <ul>
        <li class="bold red" random="23">Notebook
        </li>
        <li>Jello</li>
        <li>Spinach</li>
        <li>Rice</li>
        <li>Birthday Cake</li>
        <li>Candles</li>
    </ul>
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

以下是我的 Javascript:

var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var shoppingItem = document.getElementsByTagName("li");
var ul = document.getElementsByTagName("ul")[0];

function inputLength() {
    return input.value.length;
}

function createListElement() {
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(input.value));
    var ul = document.getElementsByTagName("ul")[0];
    ul.appendChild(li);
    input.value = "";
    return li;
}

function addElementAfterClick() {
    if (inputLength() > 0) {
        createListElement();    
    }
}

function addElementAfterPress(event) {
    if (inputLength() > 0 && event.keyCode === 13) {
        createListElement();
    }
}

function addLineThroughEvent(element) {
    element.addEventListener("click", function() {
    element.classList.toggle("done");
    });
}

function addDeleteButton(element) {
    var del = document.createElement("button");
    del.addEventListener("click", function () { // This doesn't work
        alert("You clicked")
    })
    del.appendChild(document.createTextNode("Delete"));
    element.insertAdjacentHTML("afterend", del.outerHTML);
}

input.addEventListener("keypress", addElementAfterPress);

Array.from(shoppingItem).forEach(addLineThroughEvent);

Array.from(shoppingItem).forEach(addDeleteButton);

button.addEventListener("click", addElementAfterClick);

我知道我可以使用 jQuery 解决这个问题。但是,我需要能够使用 Javascript 来解决这个问题。

【问题讨论】:

  • createListElement()创建的元素没有事件的问题吗?因为如果是这样,您就不会将事件附加到它们。它们是在开始时设置的,但不是为未来的元素设置的
  • getElementsByTagName() 中的 shoppingItem 集合只会包含调用该方法时存在的匹配项。您是否试图确保将事件添加到通过 createListElement 调用添加的新 LI 元素中?如果是这样,您可能希望在 createListElement 函数中调用 addLineThroughEvent 和 addDeleteButton。

标签: javascript html event-handling


【解决方案1】:

您仅添加不包含事件侦听的按钮 HTML。您需要使用insertAdjacentElement 为按钮附加DOM 元素。 另外,动态添加li后需要调用addDeleteButton

var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var shoppingItem = document.getElementsByTagName("li");
var ul = document.getElementsByTagName("ul")[0];

function inputLength() {
    return input.value.length;
}

function createListElement() {
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(input.value));
    var ul = document.getElementsByTagName("ul")[0];
    ul.appendChild(li);
    addDeleteButton(li)
    input.value = "";
    return li;
}

function addElementAfterClick() {
    if (inputLength() > 0) {
        createListElement();    
    }
}

function addElementAfterPress(event) {
    if (inputLength() > 0 && event.keyCode === 13) {
        createListElement();
    }
}

function addLineThroughEvent(element) {
    element.addEventListener("click", function() {
    element.classList.toggle("done");
    });
}

function addDeleteButton(element) {
    var del = document.createElement("button");
    del.addEventListener("click", function () { // This doesn't work
        alert("You clicked")
    })
    del.appendChild(document.createTextNode("Delete"));
    element.insertAdjacentElement("afterend", del);
}

input.addEventListener("keypress", addElementAfterPress);

Array.from(shoppingItem).forEach(addLineThroughEvent);

Array.from(shoppingItem).forEach(addDeleteButton);

button.addEventListener("click", addElementAfterClick);
<!DOCTYPE html>
<html>
<head>
    <title>Javascript + DOM</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>Shopping List</h1>
    <p id="first">Get it done today</p>
    <input id="userinput" type="text" placeholder="Enter items">
    <button id="enter">Enter</button>
    <ul>
        <li class="bold red" random="23">Notebook
        </li>
        <li>Jello</li>
        <li>Spinach</li>
        <li>Rice</li>
        <li>Birthday Cake</li>
        <li>Candles</li>
    </ul>
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

【讨论】:

    【解决方案2】:

    在createListElement中创建节点后需要添加事件

    var button = document.getElementById("enter");
    var input = document.getElementById("userinput");
    var shoppingItem = document.getElementsByTagName("li");
    var ul = document.getElementsByTagName("ul")[0];
    
    function inputLength() {
        return input.value.length;
    }
    
    function createListElement() {
        var li = document.createElement("li");
        li.appendChild(document.createTextNode(input.value));
        var ul = document.getElementsByTagName("ul")[0];
        ul.appendChild(li);
        input.value = "";
    addDeleteButton(li);
    addLineThroughEvent(li);
        return li;
    }
    
    function addElementAfterClick() {
        if (inputLength() > 0) {
            createListElement();    
        }
    }
    
    function addElementAfterPress(event) {
        if (inputLength() > 0 && event.keyCode === 13) {
            createListElement();
        }
    }
    
    function addLineThroughEvent(element) {
        element.addEventListener("click", function() {
        element.classList.toggle("done");
        });
    }
    
    function addDeleteButton(element) {
        var del = document.createElement("button");
        del.addEventListener("click", function () { // This doesn't work
            alert("You clicked")
        })
        del.appendChild(document.createTextNode("Delete"));
        element.insertAdjacentElement("afterend", del);
    }
    
    input.addEventListener("keypress", addElementAfterPress);
    
    Array.from(shoppingItem).forEach(addLineThroughEvent);
    
    Array.from(shoppingItem).forEach(addDeleteButton);
    
    button.addEventListener("click", addElementAfterClick);
    <!DOCTYPE html>
    <html>
    <head>
        <title>Javascript + DOM</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <h1>Shopping List</h1>
        <p id="first">Get it done today</p>
        <input id="userinput" type="text" placeholder="Enter items">
        <button id="enter">Enter</button>
        <ul>
            <li class="bold red" random="23">Notebook
            </li>
            <li>Jello</li>
            <li>Spinach</li>
            <li>Rice</li>
            <li>Birthday Cake</li>
            <li>Candles</li>
        </ul>
        <script type="text/javascript" src="script.js"></script>
    </body>
    </html>

    【讨论】:

      猜你喜欢
      • 2020-08-26
      • 1970-01-01
      • 2012-10-10
      • 2022-06-18
      • 1970-01-01
      • 1970-01-01
      • 2023-01-23
      • 1970-01-01
      • 2021-03-13
      相关资源
      最近更新 更多