提问人:Joel del Pilar 提问时间:12/12/2022 更新时间:12/12/2022 访问量:63
使用 addEventListener 和函数时避免重复代码的最佳方法
Best way to avoid repeating code when using addEventListener and functions
问:
我在编码方面很新,目前正在研究前端开发。我正在学习 JS 的第 5 周,并且遇到了使用 Typescript 创建待办事项列表的挑战。
当我在我的应用程序中创建任务时,它有一个复选框和一个“垃圾箱”按钮。垃圾桶按钮的标识非常清晰,复选框将在“选中”时将任务放在列表中的最后。
在创建事件侦听器时,我注意到了一些重复的代码。因此,我找到了一种将事件侦听器添加到多个元素的方法,但我无法思考如何调用与单击的内容相对应的不同函数。
这就是我找到一种将事件侦听器添加到每个元素的方法。但是从这里开始,我如何根据点击的内容调用函数?
document.querySelectorAll('.add-click-listener').forEach(item => {
item.addEventListener('click', event => {
})
})
这是从头开始的代码
let checkbox = Array.from(document.querySelectorAll('.hidden-checkbox'));
checkbox.forEach((item) => {
item.addEventListener('click', checkboxStatusShift);
});
let trashBtn = Array.from(document.querySelectorAll('.trash-btn'));
trashBtn.forEach((item) => {
item.addEventListener('click', deleteTask);
});
这将是“回收”任务的功能:
function deleteTask(event: any) {
const index = (event.currentTarget);
const buttonId = index.id?.replace('remove-', '');
const currentTask = todoDatabase.filter((object) => object.id === buttonId)[0];
const currentTaskId = currentTask.id;
console.log(buttonId);
console.log(currentTaskId);
if (buttonId == currentTaskId) {
todoDatabase.splice(0, 1);
printTodoList();
}
}
我还没有启动复选框函数的代码。
非常感谢我能得到的任何提示。
答:
0赞
Oro
12/12/2022
#1
根据我的经验,您可以使用事件委派模式来避免重复代码。您必须将事件侦听器附加到父元素,然后在处理程序中检查它是否与子元素匹配。单击子项的事件将冒泡,因此您将抓住它。在代码中,它将如下所示:
document.querySelector('#parent-element').addEventListener('click', function(e) {
if (e.target && e.target.matches('.child-element')) {
// do your stuff here
}
});
评论
0赞
Joel del Pilar
12/12/2022
嗨,奥罗!这个我不知道,在你的例子中,“function(e)”是匿名的吗?无论如何,坦克你的回应,我会试一试。
0赞
Oro
12/12/2022
是的,在我的示例中它是匿名的,但您可以将其设置为变量或命名函数,然后如果需要,您将能够删除侦听器
0赞
Andrey Zinoviev
12/12/2022
#2
可以绑定到复选框所在的根元素,并处理触发事件的目标元素。
如果 HTML 如下所示:
<div id="app">
<div class="checkboxes">
<input id="1" type="checkbox" /><label for="1">Checkbox 1</label>
<input id="2" type="checkbox" /><label for="2">Checkbox 2</label>
<input id="3" type="checkbox" /><label for="3">Checkbox 3</label>
</div>
</div>
示例 JS 代码如下所示:
const root = document.getElementsByClassName('checkboxes')[0];
root.addEventListener('click', function (event) {
const target = event.target;
if (target.tagName == 'INPUT') {
console.log(target.id);
console.log(target.checked);
}
});
使用类名“checkboxes”将单击事件绑定到根 div,并处理触发事件的确切人员。
如果你可以使用 Jquery,那么函数 https://api.jquery.com/on 也可以做同样的事情on
$(div.checkboxes).on("click", ".checkbox", function(event){})
评论
0赞
Joel del Pilar
12/12/2022
嗨,安德烈!感谢您的回复!我的复选框是由 JS 呈现的。每个“任务”都是一个 div,其中包含一个输入类型复选框,然后是一个标签和一个按钮元素。在这种情况下,示例代码是否仍然适用?
0赞
Andrey Zinoviev
12/12/2022
我想是的。你可以在这里试试 stackblitz.com/edit/js-sthdna?file=index.js 只需将 html 标记替换为您自己的标记即可。
1赞
Joel del Pilar
12/12/2022
#3
感谢所有的回复,这为我指明了正确的方向,我让它按预期工作,结果是以下代码:
document.querySelectorAll('.add-click-listener').forEach(item => {
item.addEventListener('click', (event: any) => {
const thisWasClicked = event.currentTarget;
let trashBtn = Array.from(document.querySelectorAll('.trash-btn'));
const filterTrashBtn: any = trashBtn.find((btn) => btn.id === thisWasClicked.id);
const findTask = trashBtn.indexOf(filterTrashBtn);
if (filterTrashBtn?.id == thisWasClicked.id) {
todoDatabase.splice(findTask, 1);
printTodoList();
}
});
});
现在,我可以使用另一个 if 和一些变量等为我的复选框编写代码。
评论
array.filter(...)[0]