【问题标题】:Something wrong with the loop in the Console控制台中的循环有问题
【发布时间】:2016-08-20 17:44:15
【问题描述】:

我创建了一个简单的代码,其中父元素 <ul> 会在每次单击时删除一个子元素 <li>。执行成功,但每次单击父元素时,控制台中都会出现一条消息,提示我的代码有问题。复制并粘贴此代码时,您会看到它:

HTML

<ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
</ul>


JavaScript

query('ul').onclick = function() {
    var childItems = Array.prototype.slice.call(this.children);
    for(var c=0; c<childItems.length; ++c) {
        while(childItems.length != 0) {
            this.removeChild(childItems[c]);
        }
    }
}


谁能告诉我我的代码有什么问题以及如何修复它?

【问题讨论】:

    标签: javascript html loops onclick console


    【解决方案1】:

    我不会在不必要的for 循环中嵌套while 循环,也不会使用Array.prototype.slice.call()。无论如何,您使用forwhile 循环实现的代码将在第一次单击时删除所有 元素,而不是一个一个地删除它们。建议的方法(例如here)是使用ul 的childNodes 成员。例如:

    yourUL.onclick = function() {
        this.removeChild(this.childNodes[0]);
    };
    

    让我把它扔在小提琴中:here

    【讨论】:

    • 为什么不使用array.protype.slice.call?还有你为什么要一一删除元素。不过,您对冗余的 while 循环是正确的。
    • @nick OP 请求“每次单击时删除一个子项,即
    • ”。这就是为什么我要一一删除它们。
  • 我不会使用Array.prototype.slice.call(),主要是因为冗余。如果已经有对象的成员childNodes,为什么还要使用别的东西?
  • 类型转换不是多余的,从 nodeList 转换后,您可以在节点数组上调用 forEach 之类的数组方法。但无论如何,如果他只是想删除一个元素,那是无关紧要的。
  • 感谢您的所有提示。我没想到会这么简单。我还不擅长编写复杂的代码。
  • 【解决方案2】:

    当你使用 slice 方法时,它会返回一个新数组。然后,当您使用 removeChild 时,您使用的是这个新数组而不是节点列表。您得到的错误与数组有关,不属于 ul 节点。

    你可以修复,

    query('ul').onclick = function(e) {
        this.removeChild(this.children[0]);
    }
    

    https://jsfiddle.net/5g6767h1/

    【讨论】:

    • 我认为不正确,对节点的引用被保留,Array.prototype.slice.call 将节点列表更改为数组结构
    • 没想到这么简单。感谢您的提示:)
    【解决方案3】:
    <ul id="TestUL">
        <li>one</li>
        <li>two</li>
        <li>three</li>
        <li>four</li>
        <li>five</li>
    </ul>
    

    var ul = document.getElementById('test');
    ul.onclick = function() {
        var childItems = Array.prototype.slice.call(this.children);
        for(var c=0; c<childItems.length; ++c) {
            while(childItems.length != 0) {
                this.removeChild(childItems[c]);
            }
        }
    }
    

    【讨论】:

    • 请解释为什么如何这比原始代码更好。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签