【问题标题】:classList.toggle() behaves strangeclassList.toggle() 行为奇怪
【发布时间】:2022-01-24 16:55:03
【问题描述】:

我正在尝试通过创建这个非常简单的待办事项应用程序来学习 Javascript。我可以在输入中输入一些值。当按下输入或提交按钮时,来自输入标签的值作为列表添加到 ul。然后一个类 'list-item' 被添加到该 li 标签中。

我的问题是:我想在单击时跨越任何单个列表。我为此使用了以下代码。我的 CSS 中有“交叉”样式,但问题是我的代码并没有跨越每个单独的列表。它跨越了所有其他的。我也试过forEach,结果是一样的。

const listItems = document.querySelectorAll('list-item');

for (let i=0; i<listItems.length; i++) {
    
    listItems[i].addEventListener('click', function() {
        console.log(listItems[i])
        listItems[i].classList.toggle('cross');
    })
}

我的整个 javascript:

const input = document.getElementById('main-input')
const submit = document.getElementById('submit')
const ul = document.getElementById('to_dos');
const del = document.getElementById('del')

//clicking submit button
submit.addEventListener('click', function() {
    addList()
})

//pressing enter key
input.addEventListener("keypress", function(event) {
    if(event.keyCode === 13) {
        event.preventDefault()
        addList()
        
    }
})

//add new todo in the list from input
const addList = () => {
    const newToDo = document.createElement('LI')
    newToDo.classList.add('list-item')
    newToDo.appendChild(document.createTextNode(input.value))
        
        
    ul.appendChild(newToDo)
    input.value = "" 
    
    //cross the completed tasks
    const listItems = document.querySelectorAll('li.list-item');
    
    for (let i=0; i<listItems.length; i++) {
        
        listItems[i].addEventListener('click', function() {
            console.log(listItems[i])
            listItems[i].classList.toggle('cross');
        })
    }


    //delete button
    del.addEventListener('click', function() {
        const completedItems = document.querySelectorAll('.cross');
        completedItems.forEach(
            completedItem => {
                completedItem.classList.add('hide')
            }
        )
    })
}

【问题讨论】:

    标签: javascript jquery dom queryselector


    【解决方案1】:

    在您的 codepen 中,您错误地分配了点击侦听器。不是将侦听器单独附加到每个添加的项目,而是在每次添加新项目时循环遍历所有项目 - 当您像这样复合事件侦听器时,它可能会产生不希望的结果。

    在您的 addList 函数中,而不是使用此循环遍历所有输入:

            //cross the completed tasks
            const listItems = document.querySelectorAll('li');
            
            listItems.forEach(listItem => listItem.addEventListener('click', e => {
                e.target.classList.toggle('cross');
            }))
    

    只需将监听器附加到新添加的监听器:

            newToDo.addEventListener('click', e => {
                e.target.classList.toggle('cross');
            })
    

    示例:https://codepen.io/chayashital/pen/jOGaWgJ#_=_

    【讨论】:

    • 我按照您的建议编辑了我的代码。不幸的是,它还没有做出改变
    • 对我来说很奇怪的是它适用于备用列表?。如您所见,我的代码笔:codepen.io/chayashital/pen/jOGaWgJ
    • 我查看了 codepen 并更改了答案。看看它是否有帮助
    【解决方案2】:

    您只是忘记在 querySelectorAll 方法的开头添加点 (.)。 在您的情况下,您告诉 querySelectorAll 方法来查找所有 list-item 标记,这样 dot 将更改查找所有 list-item 类的含义。 并且 querySelectorAll 将返回 HTMLCollection 而不是 Array 因此 forEach 方法将不起作用,您应该将其返回到 Array 使用 Array() 函数或以下方式。

    [...document.querySelectorAll('.list-item')]
    .forEach(function(element){
        element.addEventListener("click", function(){
            element.classList.toggle("cross")
    })
    })
    

    【讨论】:

    • 谢谢。我根据您的建议编辑了代码,但它的行为仍然相同。
    猜你喜欢
    • 2013-08-25
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多