【问题标题】:Adding event listeners to <li> that are created using javascript将事件侦听器添加到使用 javascript 创建的 <li>
【发布时间】:2017-09-04 06:32:51
【问题描述】:

我对在 JS 中操作 DOM 中的元素非常陌生,因此我正在创建一个简单的待办事项列表以使我更加舒适,并且我可以使用输入添加项目并通过单击列表项目来删除项目。 虽然这可能不是最佳实践和限制,但我只是想使用创建和删除元素而不是使用对象或类,直到我更熟悉,也使用普通/香草 js,所以请在回答时记住这一点。

我正在尝试添加一个单击事件,当单击 &lt;li&gt; 时删除 &lt;li&gt;

我的逻辑是... 加载页面时,我不能只对所有 &lt;li&gt;s 运行 for 循环并添加事件处理程序,因为所有 &lt;li&gt; 尚不存在。 所以我尝试的解决方案是当 addTaskButton 事件被触发时,我们得到事件发生时页面上的所有&lt;li&gt;,我们遍历所有这些并添加一个事件监听器到&lt;li&gt;等待点击时被移除。

这似乎不起作用,可能过于复杂。

有人可以像我 5 岁一样简单地向我解释为什么这不起作用或有什么更好的方法来做到这一点?

提前谢谢你

HTML

<ul id="taskList">
    <li>example</li>

</ul>
<input type="text" id="addTaskInput">
<button id="addTaskButton">Add Task</button>

JavaScript

const taskList = document.querySelector("#taskList");
const addTaskInput = document.querySelector("#addTaskInput");
const addTaskButton = document.querySelector("#addTaskButton");
let taskItem = document.querySelectorAll("li");


addTaskButton.addEventListener("click", () => {
    let taskItem = document.createElement("li");
    taskItem.textContent = addTaskInput.value;
    for (let i = 0; i < taskItem.length; i++) {     
        taskItem[i].addEventListener("click", () => {
            let taskItem = document.querySelectorAll("li");
            taskList.removeChild(taskItem[i]);      
        });
    }
    taskList.appendChild(taskItem);
    addTaskInput.value = " ";
});

【问题讨论】:

标签: javascript for-loop addeventlistener removechild dom-manipulation


【解决方案1】:

这是我为您的要求创建的代码,它在 vanilla javascript 中实现了 jQuery $(document).on 机制,现在无论您在文档中创建一个 li 的位置,点击该 li 它将被删除。

说明

它所做的是点击文档,它检查哪个元素被点击(e.target 是被点击的元素,e 是文档上的点击事件),然后检查被点击的项目是否是一个 li 标签(例如。 target.tagName 将告诉我们标签名称(如果项目被点击),所以如果它是一个 li 就删除它;

	const taskList = document.querySelector("#taskList");
	const addTaskInput = document.querySelector("#addTaskInput");
	const addTaskButton = document.querySelector("#addTaskButton");


	addTaskButton.addEventListener("click", () => {
	    let taskItem = document.createElement("li");
	    taskItem.textContent = addTaskInput.value;
	    taskList.appendChild(taskItem);
	    addTaskInput.value = " ";
	});

	document.onclick = function(e)
	{
	  if(e.target.tagName == 'LI'){
	     e.target.remove();
	   }
	}
<ul id="taskList">
    <li>example</li>

</ul>
<input type="text" id="addTaskInput">
<button id="addTaskButton">Add Task</button>

【讨论】:

  • document.onclick = function(e) { if(e.target.tagName == 'LI'){ e.target.remove();你能解释一下这是如何工作的吗?因为 e 不是定义的函数?
【解决方案2】:

像这样更新你的 for 循环:

for (let i = 0; i < taskItems.length; i++) {     
    taskItems[i].addEventListener("click", () => 
        taskList.removeChild(taskItems[i]);      
    });
}

您的初始 taskItem 变量也应该是 taskItems 并反映在上面的 for 循环中。

【讨论】:

    【解决方案3】:
    taskList.addEventListener("click", (event) => {
         event.target.remove();
    });
    

    当指定的事件发生时,事件对象被返回。 事件对象有几个属性,其中之一是目标元素,它是事件发生的元素。 event.target 返回给我们,我们正在将 remove() 方法应用于 event.target

    由于事件“冒泡”或“事件传播”,我们可以将事件处理程序附加到祖先。最好将事件侦听器附加到始终位于 DOM 中的最近的祖先元素(不会被删除)。

    当一个事件被触发时——在这种情况下是“点击”事件。所有降序元素都将被删除——在我们的例子中,因为只有&lt;li&gt;,这很好。但我们应该更具体,因为在不同的情况下,我们可以将此事件处理程序附加到具有多个不同元素的 div。

    为此,我们添加一个 if 条件来检查 tagName 是否为 &lt;li&gt;

    if (event.target.tagName == "LI") 
    

    注意元素必须大写

    解决方法如下

    taskList.addEventListener("click", (event) => {
    
          if(event.target.tagName == "LI"){
             event.target.remove();
        }});
    

    延伸阅读:

    事件对象及其属性: https://developer.mozilla.org/en-US/docs/Web/API/Event

    事件冒泡: https://developer.mozilla.org/en-US/docs/Web/API/Event/bubbles

    标签名称: https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName

    【讨论】:

      猜你喜欢
      • 2021-04-17
      • 1970-01-01
      • 2021-09-06
      • 2012-11-26
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多