函数返回的DOM元素绑定addEventListener事件监听器不生效如何解决?
问题根因
你绑定了事件的待办项实例根本没有被插入到页面DOM中。看表单提交逻辑里的代码:
// 1. 第一次调用createToDoItem生成实例,给这个实例的按钮绑定了事件 let todoItem = createToDoItem(form.input.value); console.log(todoItem.doneButton) todoItem.doneButton.addEventListener('click', function () { console.log('done button clicked'); }); todoItem.deleteButton.addEventListener('click', ()=> { console.log('delete button clicked'); }) // 2. 这里你又调用了一次createToDoItem,生成了**全新的、没有绑定任何事件的实例**,把这个新实例的DOM插到了列表里 list.append(createToDoItem(form.input.value).item)
你console.log出来的是第一个实例的按钮,但是页面上渲染的是第二个完全独立的实例,事件当然不会触发。
修复方案
直接把绑定过事件的todoItem的item节点插入列表即可,把append那行改成:
list.append(todoItem.item)
另外你初始渲染的三个默认待办项也没有绑定事件,如果需要的话,可以封装通用的绑定事件函数,创建完实例之后统一调用。
修复后完整JS代码参考
(function() { function createAppTitle(title) { let appTitle = document.createElement('h2'); appTitle.textContent = title; appTitle.classList.add('mt-5', 'mb-3'); return appTitle; } function createToDoList() { let list = document.createElement('ul') return list; } function createToDoForm() { let buttonWrapper = document.createElement('div') let form = document.createElement('form') let input = document.createElement('input') let button = document.createElement('button') form.classList.add('input-group', 'mb-3'); input.classList.add('form-control'); input.placeholder = 'Enter the name of the task'; buttonWrapper.classList.add('input-group-append'); button.classList.add('btn', 'btn-primary'); button.textContent = 'Add a task'; buttonWrapper.append(button); form.append(input); form.append(buttonWrapper); return { form, input, button }; } function createToDoItem (name) { let item = document.createElement('li') let buttonGroup = document.createElement('div') let doneButton = document.createElement('button') let deleteButton = document.createElement('button') item.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center'); item.textContent = name; buttonGroup.classList.add('btn-group','btn-group-sm'); doneButton.classList.add('btn','btn-success'); doneButton.textContent = "Done"; deleteButton.classList.add('btn','btn-danger'); deleteButton.textContent = 'Delete'; buttonGroup.append(doneButton); buttonGroup.append(deleteButton); item.append(buttonGroup); return { item, doneButton, deleteButton } } // 封装通用的待办项事件绑定逻辑 function bindTodoItemEvents(todoItem) { todoItem.doneButton.addEventListener('click', function () { console.log('done button clicked'); // 可扩展完成逻辑:给待办项加成功样式 todoItem.item.classList.toggle('list-group-item-success') }); todoItem.deleteButton.addEventListener('click', ()=> { console.log('delete button clicked'); // 可扩展删除逻辑:二次确认后移除节点 if(confirm('确定要删除这个待办吗?')) { todoItem.item.remove() } }) } document.addEventListener('DOMContentLoaded', function () { let container = document.querySelector('.container'); let appTitle = createAppTitle('Name of the Target'); let list = createToDoList(); let form = createToDoForm(); let todoItems = [createToDoItem('Book your trip'), createToDoItem('Fly to Dubai'), createToDoItem('Book your trip')]; container.append(appTitle); container.append(form.form); container.append(list); // 给默认待办项绑定事件后再插入列表 todoItems.forEach(item => { bindTodoItemEvents(item) list.append(item.item) }) form.form.addEventListener('submit', (e)=> { e.preventDefault(); if (!form.input.value) { return; } let todoItem = createToDoItem(form.input.value); // 绑定事件 bindTodoItemEvents(todoItem) // 插入已经绑定好事件的实例节点 list.append(todoItem.item) form.input.value = ''; }); }) })();
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

