循环删除子元素,却只删除了最后一个?

我用的zepto,一开始,采用如下代码:

let parent = $('.parent'),
  child = parent.find('.child');

for (let i = 0; i < 5; i++) {
  child.eq(-1).remove();
}

我的本意是希望删除最后五个子元素,但实际却只删除了最后一个。

我知道,可以通过如下代码删除:

let parent = $('.parent');

for (let i = 0; i < 5; i++) {
  parent.find('.child').eq(-1).remove();
}

这段代码。应该是每次循环,每次去查询dom,所以依次删了最后五个。

但我的疑问是,为何第一段代码不行?第一段里的 child 不会去查询dom结构吗?

阅读 2.1k
评论
    4 个回答
    • 41.6k

    @SlaneYang 已经回答了问题的关键,注意 $.fn.remove()Array.prototype.pop() 是不一样的,后者是直接对数据进行操作,前者是从 DOM 树删除 DOM 元素(但元素仍然存在于内存,由 jQuery 对象/数组引用)

    对于你这个问题,其实我建议先通过 .filter() 把需要的元素过滤出来,再一次性 remove()

    const parent = $(".parent");
    const children = parent.find(".child");
    const firstIndexForRemoving = children.length - 5;
    children.filter(i => i >= firstIndexForRemoving).remove();

    顺便提一下

    • 我这个答案不是解决你的问题,只是锦上添花,喜欢请赞,但不太适合采纳
    • 对于不会再改变的变量,建议使用 const 声明而不是 let 声明
    • 尽量不要在声明变量的时候使用逗号运算符一次声明多个变量(压缩工具会自动处理成这种结果,但自己写代码不要这么写),尤其是对变量立即初始化的时候
    • child 在原程序中表示若干子项,应该使用复数 children 更为准确

      假如parent下'.child'共有10个。
      第一段代码中child = parent.find('.child');child变量是被缓存起来的,每次调用child.eq(-1).remove();child都是缓存的那10个元素,然后删除最后一个,重复了5次。

      第二段代码中,则没有缓存的问题,每次for循环都会去查一遍parent下面现在有多少个.child元素,并且删除最后一个。

      总结来说,就是第一段代码只查询了一次parent下的所有.child,而第二段代码,每次for循环都会去查询一遍。

      望采纳

        • 6.6k
        let parent = $('.parent');
        // 这里的parent.find('.child')只执行了一次,然后用child变量暂存起来了。
        // let child = parent.find('.child');
        for (let i = 0; i < 5; i++) {
           // 而这里的child在循环里,所以执行了多次。
           var child = parent.find('.child');
           child.eq(-1).remove();
        }
        // 比如:
        var sum = 0;
        for (var i = 0; i < 5; i++) {
            console.log(sum++); // 输出0、1、2、3、4
        }
        
        for (var i = 0; i < 5; i++) {
            var sum2 = 0; // 每次循环sum2都是0
            console.log(sum2++); // 所以这里连续输出了5次0
        }
        // 这样是不是理解了些。(望采纳)
          • 5.7k

          第一个是获取到子元素形成了一个伪数组,记住是伪数组,而且在循环之前里面的元素就固定了,这样你循环删除其最后一个元素其实指向的就是最后一个,而放在里面查找子元素形成新的伪数组进行删除,每次就能删除到最后一个。
          关于伪数组和数组这是有区别的,不能混为一谈,操作数组的结果和操作伪数组可不一定会得到一样结果。

            撰写回答

            登录后参与交流、获取后续更新提醒

            相似问题
            推荐文章