【问题标题】:Adding event listeners to dynamically added list elements将事件侦听器添加到动态添加的列表元素
【发布时间】:2019-10-23 06:35:11
【问题描述】:

我对 JavaScript 编程非常陌生,我正在尝试学习 JavaScript 中的事件处理程序。我在动态创建的元素上添加事件处理程序。我制作了一个简单的购物清单代码,通过它我可以将数据输入到列表中,并在每个项目的右侧添加了一个删除图标。我在该图标上添加了事件处理程序,但它仅适用于列表中的项目而不是动态添加的。

我试图找出方法,大约一天,但仍然无法找出使用纯 JavaScript 实现此目的的正确方法。我已经阅读了关于堆栈溢出和许多其他资源的几乎所有答案,但仍然无法获得解决方案,我在找出解决方案时求助于堆栈溢出的答案之一,即纯 JavaScript,

问题链接:add event listener on elements created dynamically

问题与我的相似,但我按照答案所述尝试了,但仍然不适合我。

document.querySelector("ul").addEventListener('click', function(event) {
    if (event.target.tagName === "I") {
        alert("hmm.. you clicked.");
    }
});

小提琴链接:https://jsfiddle.net/65erpycb/

var input = document.getElementById("userinput");
var enter = document.getElementById("enter");
var ul = document.querySelector("ul");
var listItem = document.querySelectorAll("li");

function toggleFunction(e) {
    if(e.target.tagName === "LI") {
        e.target.classList.toggle("done");
    }
}

function addListItemOnClick() {
    if (input.value.length > 0) {
        console.log(input.value.length);
        var li = document.createElement("li");
        li.appendChild(document.createTextNode(input.value));
        ul.appendChild(li);
        input.value = "";
        var d = document.createElement("div");
        d.classList.add("fas", "fa-trash");
        li.appendChild(d);
    }
}
function addListItemOnPress() {
    if (input.value.length > 0 && event.keyCode === 13) {
        var li = document.createElement("li");
        li.appendChild(document.createTextNode(input.value));
        ul.appendChild(li);
        input.value = "";
        var d = document.createElement("div");
        d.classList.add("fas", "fa-trash");
        li.appendChild(d);
    }
}
enter.addEventListener("click", addListItemOnClick);
input.addEventListener("keypress", addListItemOnPress);
ul.addEventListener("click",toggleFunction);

document.querySelector("ul").addEventListener('click', function(event) {
    if (event.target.tagName === "I") {
        alert("hmm.. you clicked.");
    }
});
.box {
    text-align: center;
    border: 2px solid black;
}

h1 {
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    font-size: 50px;
}

#first {
    font-size: 25px;
    font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
    text-decoration: underline;
}

ul {
    border: 1px solid black;
    padding: 0;
}

li {
    display: block;
    list-style: none;
    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
    font-size: 15px;
    text-align: center;
    text-decoration: underline;
}

#userinput {
    text-align: center;
}

.done {
    text-decoration: line-through;
}

.fa-trash {
    float: right;
}
<!DOCTYPE html>
<html>
<head>
	<title>Javascript + DOM</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div class="box">
	<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 id = "items">
		<li>Notebook<i class="fas fa-trash"></i></li>
		<li>Jello<i class="fas fa-trash"></i></li>
		<li>Spinach<i class="fas fa-trash"></i></li>
		<li>Rice<i class="fas fa-trash"></i></li>
		<li>Birthday Cake<i class="fas fa-trash"></i></li>
		<li>Candles<i class="fas fa-trash"></i></li>
	</ul>
	</div>
	<script type="text/javascript" src="script.js"></script>
	<script src="https://kit.fontawesome.com/28803a998e.js"></script>
</body>
</html>

我希望删除按钮在我动态添加项目时也应该起作用。

【问题讨论】:

  • 我建议您将 addListItemOnPress 函数的代码添加到问题中。链接到小提琴是一个很好的开始,尽管它不完全符合此处“完整”问题的 SO 定义stackoverflow.com/help/minimal-reproducible-example 通过添加该函数实现,任何人都可以重现您描述的确切问题。
  • 啊,还有答案 cmets 中提到的 addListItemOnClick。

标签: javascript html


【解决方案1】:

添加的项目是div 标签元素。但原始项目是i 标签元素。 event.target.tagName === "I" 测试只会匹配 i 标签,而不匹配 div 标签。

更新添加的项目代码(addListItemOnClickaddListItemOnPress):

document.createElement("div")

成为:

document.createElement("i")

【讨论】:

  • 啊,你有几个函数 addListItemOnClick 和 addListItemOnPress。当我将两者都从 div 更改为 i 时,它对我有用。
  • @Will Cain,那么我应该将 event.target.tagName === "I" 更改为 event.target.tagName.toLowerCase() === "i";也
  • 大写 event.target.tagName === "I" 为我工作。请参阅stackoverflow.com/questions/27223756/… 或我上面的小提琴。
【解决方案2】:

如果您分离数据和查看并使用 html-inline 绑定(对于小型项目是 acceptable - 并且类似于 angular/react/vue 框架中的模板...)代码会更小更干净

let data=[
  { name: "Notebook" },
  { name: "Jello" },
  { name: "Spinach" },
  { name: "Rice" },
  { name: "Birthday" },
  { name: "Candles" },
];

function add() {
  data.push({ name: userinput.value });
  userinput.value='';
  refresh();
}

function del(i) {
  data.splice(i,1);
  refresh();
}

function refresh() {
  items.innerHTML = data.map((x,i)=> `
    <li>${x.name}<i class="fas fa-trash" onclick="del(${i})"></i></li>
  `).join('');
}

refresh();
<div class="box">
  <h1>Shopping List</h1>
  <p id="first">Get it done today</p>
  <input id="userinput" type="text" placeholder="enter items">
  <button id="enter" onclick="add()">Enter</button>

  <ul id="items"></ul>

</div>

<script src="https://kit.fontawesome.com/28803a998e.js"></script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 2021-03-21
    • 1970-01-01
    相关资源
    最近更新 更多