点击事件仅在第二次点击时触发

时间:2020-05-09 21:35:43

标签: javascript

我有一个使用本地存储的待办事项列表。所有数据都是动态填充的。要为删除图标添加事件监听器,我在列表的父级上使用了事件委托。

我正在尝试将事件添加到单选按钮,但是仅当我单击第二个单选按钮时,该事件才起作用。第一次单击项目不会注册警报。即,如果我单击第一个收音机,则事件从第三个收音机触发,第三个收音机则触发第三个收音机。

我有一个js小提琴-https://jsfiddle.net/bne25kx8/-您将可以通过输入内容并按Enter来填充列表

itemslist.addEventListener('click', handleCheck);

function handleCheck(e){
if (!e.target.matches('input[name="checked"]')) return;

const checkboxes = document.querySelectorAll('input[name="checked"]');
checkboxes.forEach(checkbox => checkbox.addEventListener('click', function(){
    alert(checkbox);
}));

}

3 个答案:

答案 0 :(得分:0)

您的handleCheck()函数在第一次单击时运行。然后,该函数将事件侦听器分配给复选框,这就是为什么它们在第一次单击后都可以工作的原因。


在您的匿名函数中,您需要添加e参数,否则您的e.target.whatever无法正常工作。

checkboxes.forEach(checkbox => checkbox.addEventListener('click', function(e){

删除handleCheck功能。

function handleCheck(e){
if (!e.target.matches('input[name="checked"]')) return;

删除将事件侦听器添加到itemsList的行。

itemslist.addEventListener('click', handleCheck);

然后用此代码替换剩下的内容...

const checkboxes = document.querySelectorAll('input[name="checked"]');
checkboxes.forEach(checkbox => checkbox.addEventListener('click', function(e){
     if (!e.target.matches('input[name="checked"]')) {
         alert(this);
     }
}));

答案 1 :(得分:0)

那是因为您要在第一个click事件之后将处理程序添加到click事件的复选框中。如果要捕获首次点击,则必须在创建之前添加事件处理程序。

答案 2 :(得分:0)

以下是您的小提琴的一些变化:https://jsfiddle.net/wej97rv3/

我移动了一些代码,以便您在创建时将事件处理程序绑定到新的复选框。

function populateList(items, list){
    list.innerHTML = items.map((item, index) => {
        return `
            <div class="list__item" data-index=${index}>
                <input type="checkbox" name="checked" class="list__item-check">
                <p class="list__item-item">${item.text}</p>
                <span class="trash">X</span>
            </div>`;
    }).join('');
    // The following lines used to be in handleCheck()
    const checkboxes = document.querySelectorAll('input[name="checked"]');
    checkboxes.forEach(checkbox => checkbox.addEventListener('click', function(){
        alert(checkbox);
    }));
}

您以前的handleCheck方法是将事件处理程序应用于已经具有事件处理程序的复选框。

另外,注释掉这一行:

//itemslist.addEventListener('click', handleCheck);

因为不再需要