You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数返回的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:27:03