javascript - Removing elements from dom using queryselectorall, jquery, getelementsbyid, getelementsbyclassname - Stack Overflow

I am writing a function for a library that takes an object of elements and removes it from the DOM.I

I am writing a function for a library that takes an object of elements and removes it from the DOM. I have this working fine but was wondering if there is a way to do a single for loop? I found that NodeLists and HTMLCollections can't use the same for loop so I build an array then remove the elements with the same loop.

   _remove = function(elem) {
      if(!elem) { return false; }
      // getElementById
      if(!elem.length) {
        if(elem.parentNode) {
          elem.parentNode.removeChild(elem);
        }
      // querySelectorAll, jquery, getElementsByClassName, getElementsByTagName
      } else {
        var elems = [];
        for(var j = 0; j<elem.length; j++) {
          if(elem[j]) {
            elems.push(elem[j]);
          }
        }
        for(var i=0; i<elems.length; i++) {
          if(elems[i].parentNode) {
            elems[i].parentNode.removeChild(elems[i]);
          }
        }
        return false;
      }
    }

called by:

_remove(document.getElementById('someId'));
_remove(document.getElementsByClassName('someClass'));
_remove(document.getElementsByTagName('tag'));
_remove($('#someId));
_remove($('.someClass));
_remove(document.querySelectorAll('someID or Class or Tag));

I am writing a function for a library that takes an object of elements and removes it from the DOM. I have this working fine but was wondering if there is a way to do a single for loop? I found that NodeLists and HTMLCollections can't use the same for loop so I build an array then remove the elements with the same loop.

   _remove = function(elem) {
      if(!elem) { return false; }
      // getElementById
      if(!elem.length) {
        if(elem.parentNode) {
          elem.parentNode.removeChild(elem);
        }
      // querySelectorAll, jquery, getElementsByClassName, getElementsByTagName
      } else {
        var elems = [];
        for(var j = 0; j<elem.length; j++) {
          if(elem[j]) {
            elems.push(elem[j]);
          }
        }
        for(var i=0; i<elems.length; i++) {
          if(elems[i].parentNode) {
            elems[i].parentNode.removeChild(elems[i]);
          }
        }
        return false;
      }
    }

called by:

_remove(document.getElementById('someId'));
_remove(document.getElementsByClassName('someClass'));
_remove(document.getElementsByTagName('tag'));
_remove($('#someId));
_remove($('.someClass));
_remove(document.querySelectorAll('someID or Class or Tag));
Share Improve this question edited Oct 31, 2014 at 1:49 lapin 2,1483 gold badges22 silver badges32 bronze badges asked Oct 31, 2014 at 0:55 user1572796user1572796 1,0572 gold badges21 silver badges48 bronze badges 3
  • Iterate in reverse, and you'll be covered for both types of lists. – user1106925 Commented Oct 31, 2014 at 1:01
  • can you give an example? I used both types of loops because while NodeLists were working with the 2nd loop by itself HTMLCollections were removing items reducing i as the loop was running...so half the items in the collection were not getting removed – user1572796 Commented Oct 31, 2014 at 1:02
  • Start with i as the last index instead of the first, and decrement instead of incrementing. – user1106925 Commented Oct 31, 2014 at 1:03
Add a ment  | 

2 Answers 2

Reset to default 5

Some of these functions return a live NodeList, which means that when you change the DOM, the collection changes immediately to reflect this. That's why a normal for loop doesn't work: when you remove elem[0], all the other entries in the collection move down. Then when you increment the index, you skip over the new elem[0].

The easiest way to work around this is to loop from the high end down, instead of from 0 up.

for (var j = elem.length-1; j >= 0; j--) {
    if (elem[j].parentNode) {
        elem[j].parentNode.removeChild(elem[j]);
    }
}

I would remend a bit more robust implementation for these reasons:

  1. If it's a jQuery object passed in, then you should call the jQuery .remove() because jQuery may leak memory for data and event listeners if you don't let jQuery remove DOM elements that jQuery operations such as .data() or .on() have been used with.

  2. It's not enough to just do if (elem.length) because it could still be a nodeList or an Array with a .length of 0. I changed it to test to see if that property actually exists. FYI, if you want a more robust test to see if it's an actual single DOM node, there's a robust function to do that here, though I'm not sure that's needed here.

  3. To protect against a dynamic nodeList changing out from under you or children and parents both being in the list (you don't want to remove parent before child), it is best to iterate the nodeList backwards from back to front (you don't have to make a copy).

  4. If this is just a normal array of DOM elements that are not necessarily in document order and there are parent/child elements both in the list and out of order or anyone passes you an array with any old DOM elements in it, you could end up getting an exception on a .removeChild() operation so it is best to just catch any exceptions that might happen there so the operation can always plete through the whole list, even if there is a bad element in the list.

  5. Your code did not have a consistent return value. It had one path that wasn't returning anything. I changed it to return false if nothing elem was falsey and true if it was processed. You can obviously modify this as desired, but if you're going to have a meaningful return value, you should have a return value for all code paths (you didn't have one if it was a single DOM node).

Remended code:

// _remove(elem) - remove one or more DOM nodes from their DOM hierarchy
// elem can be an Array of DOM nodes or a pseudo-array like a nodeList 
// or elem can be a single DOM element

function _remove(elem) {
    if (!elem) {
        return false;
    } else if (typeof elem.jquery === "string" && typeof elem.remove === "function") {
        // if a jQuery object, it should be removed with jQuery 
        // so jQuery data and event listener stuff will get cleaned up
        // there are more prehensive ways to check for a jQuery object,
        // but those are probably not needed here
        elem.remove();
    } else if (elem.nodeType) {
        // single DOM node
        // could also do more prehensive test to see if it's really a DOM node, 
        // but probably not needed
        if (elem.parentNode) {
            elem.parentNode.removeChild(elem);
        }
    } else if (typeof elem.length === "number") {
        // array or pseudo-array here
        // querySelectorAll, getElementsByClassName, getElementsByTagName or 
        // an array of DOM elements assembled by any other code
        // iterate backwards so if it is a dynamic nodeList, then children will be
        // be removed before parents and any nodeList changes will happen after our
        // iteration point
        for (var i = elem.length - 1; i >= 0; i--) {
            // catch errors in case anything has already been deleted
            // from a prior parent delete so we don't abort early
            try {
                elem[i].parentNode.removeChild(elem[i]);
            } catch(e) { }
        }
    } else {
        // don't know what was passed here - not something we were expecting
        return false;
    }
    return true;
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744668006a4586868.html

相关推荐

  • win 7系统怎么看计算机配置,windows7系统怎么查看电脑配置

    通常我们在选购电脑的时候都比较注重电脑配置&#xff0c;那么windows7系统怎么查看电脑配置呢?接下来大家跟着学习啦小编一起来了解一下windows7查看电脑配置的解决方法吧。 windows7查看电脑配置方法一&#x

    1小时前
    00
  • VMware虚拟机设置为固定IP

    操作原因:安装完成虚拟机后会生成一个IP,由于ip变化导致搭建好的k8s集群无法启动。因此将虚拟机配置为固定IP1、修改虚拟网络编辑器:打开虚拟网络编辑器,修改NAT设置:2、修改电脑的虚拟网卡地址选中这个网卡-->点击右键-->

    1小时前
    00
  • 很干!dockerfile最佳实践

    为什么你打包的镜像那么大?为什么打包过程耗时这么久?导致整个部署的效率很低,如果你有这样的疑问,那么很多时候是因为dockerfile的问题,这篇文章将会深入介绍dockerfile的最佳实践,帮助你构建更高效、更小、更可维护的镜像。缓存机

    1小时前
    00
  • Python 爬虫如何伪装 Referer?从随机生成到动态匹配

    一、Referer 的作用与重要性Referer 是 HTTP 请求头中的一个字段,用于标识请求的来源页面。它在网站的正常运行中扮演着重要角色,例如用于统计流量来源、防止恶意链接等。然而,对于爬虫来说,Referer 也可能成为被识别为爬虫

    1小时前
    00
  • Power BI Vega 条形纵向折线组合图表

    条形图和纵向折线图组合常用来展示绝对值和率值的组合。之前在知识星球分享过SVG的版本(使用内置表格加载),今天换一种实现方式,使用Deneb视觉对象:把需要展示的维度和指标拖拽到Deneb,本例维度为城市,绝对值为[kpi]度量值,率值为[

    59分钟前
    00
  • 苹果电脑装win7系统问题

    安装中问题&#xff1a; Windows 未能启动。原因可能是最近更改了硬件或软件。解决此问题的步骤&#xff1a; 1. 插入Windows 安装光盘并重新启动计算机。 2. 选择语言设置&#xff0c;然后单击

    53分钟前
    00
  • 基于PacBio HiFi数据的人类全基因组重测序变异分析流程

    随着第三代测序技术,特别是PacBio HiFi(High Fidelity)测序技术的发展,我们能够获得兼具长读长和高准确度的测序数据。这为人类全基因组重测序(WGS)分析,尤其是复杂区域和结构性变异(Structural Variati

    52分钟前
    00
  • 瞧瞧别人家的日期处理,那叫一个优雅!

    前言在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间。比如:2025-04-21、20250421、2025年04月21日等等。有些字段是String类型,有些是Date类型,有些是Long类型。如果不同的数据类型,经

    50分钟前
    00
  • 扣子空间能战否?我看行~

    最近扣子推出了新模块:扣子空间,功能和前段时间刷屏的Manus类似,就是帮你一步到位完成任务。扣子空间地址:扣子空间现在还没完全开放,需要有邀请码,没邀请码的同学先加入等候名单,然后静静等待~这个扣子空间和普通的AI聊天工具有什么不一样呢?

    49分钟前
    00
  • 皮尔兹Pnoz c1c2安全继电器配置与接线

    PNOZ compact是皮尔兹的一款经济型的安全继电器系列,价格实惠,空间紧凑,适用于安装急停按钮、安全门或光障光栅 等安全产品。PNOZ C1是适用急停按钮或安全门开关。PNOZ C2用于 4 类光障或带 OSSD 输出的传感器的安全

    44分钟前
    00
  • CMeas度量体系建设:让数据驱动更科学

    本文来自腾讯蓝鲸智云社区用户: CanWay研发效能度量在企业数字化转型中至关重要。它有助于企业全面量化研发过程,洞察业务绩效,识别效能瓶颈或提效机会、优化资源配置,并为决策提供有力支撑,持续推动企业研发效能优化提升。目前,效能度量已不局限

    40分钟前
    00
  • MTVInpaint:多任务视频修复框架,以双分支注意力与两阶段流水线统一完成、插入任务,处理长视频 !

    视频修复涉及在视频中修改局部区域,确保空间和时间上的一致性。现有的大多数方法主要集中在场景完成(即填补缺失区域)上,并缺乏以可控方式在场景中插入新目标的能力。幸运的是,最近在文本到视频(T2V)扩散模型方面的进展为文本指导的视频修复铺平了

    32分钟前
    20
  • Oracle中删除的列数据可以进行恢复么?

    有朋友提出闪回可以恢复删除的列(包括数据),这个可行么?实践是检验真理的唯一标准,创建一张测试表,代码语言:javascript代码运行次数:0运行复制CREATE TABLE t_flash_01 (id NUMBER, c1 varch

    30分钟前
    20
  • AI 英语能力评估App的开发

    开发一款 AI 英语能力评估 App 是一个系统工程,它结合了移动应用开发、后端服务构建、人工智能模型研发和教育评估理论。整个过程比开发一个普通 App 要复杂得多,需要多领域的技术和专业知识。以下是开发这样一个 App 的关键环节。1.

    27分钟前
    20
  • win10系统缓存在哪win10系统缓存在哪看这里

    在 Windows 10 系统中&#xff0c;缓存被存储在多个不同的位置&#xff0c;了解这些位置对于优化系统性能和管理磁盘空间至关重要。 一、临时文件缓存 按下“WindowsR”组合键&#xff0c;输入

    25分钟前
    20
  • goframe这个劲爆的脚手架做项目还是非常不错

    goframe一个由国人封装的go语言框架,模块化的设计理念非常不错。要学习goframe框架内的相关技术,找一个成熟的系统进行研读是入门提高的不错选择。今天分享一个基于goframe框架的开发的后台管理系统。功能非常不错,而且前后端代码都

    24分钟前
    00
  • AI|微信又又又有大动作了,直接把Deepseek变成了你的微信好友!

    腾讯又又又放大招了!在全球都在AI的浪潮中,以及年初Deepseek横空出世,使得中国的AI开始“吊打”海外的AI后,国内的AI使用也如雨后春笋般层出不穷。但是对于很多人来说AI的使用依然是一个门槛儿,手机上需要安装APP或者各种小程序跳转

    22分钟前
    20
  • MODIS遥感影像批量下载方法

      本文介绍在Earthdata中批量下载MODIS遥感影像各产品数据的方法。  前期我们介绍了批量下载Landsat与MODIS等遥感影像的最新可行方法,本文则再介绍一种基于Earthdata的MODIS批量下载方法。但要注意,此方法有的

    20分钟前
    20
  • OFC 2025 TeraHop报告:AI数据中心光连接技术

    在人工智能技术快速发展的背景下,AI数据中心的建设对光模块技术提出了更高要求。TeraHop在OFC 2025会议上的报告,深入探讨了这一领域的现状与未来。一、AI数据中心光互连面临的挑战(一)传输速率升级加速过去光

    19分钟前
    00
  • Nature证实:ChatGPT能够有效辅助医生提升决策准确率

    近期,Nature Medicine 刊登了一篇关于GPT-4在临床应用的文章《GPT-4 assistance for improvement of physician performance on patient care tasks:

    5分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信