最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

    正文概述 掘金(云的世界)   2021-08-10   491

    这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战。

    前言

    关于【SSD系列】:
    前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。

    先提问一波:(无框架前提下)

    • 常用查询节点方法有哪些

    • 什么是空白节点??她又到底是个什么东西

    • querySelectorAll 有哪些坑

    • 怎么查询伪元素

    • 四种删除节点方式你都知道吗

    • HTMLCollection 和 NodeList的区别

    • 怎样删除所有的孩子节点

    我们已经先jquery, vue, react等前端框架带来的便利了:

    • jquery就不说了,一个$走天下,无限连。
    • vue和react使用ref就能拿到对应节点。

    离开了这些框架,你还能666的操作Node节点吗?

    本文源码

    crud-doms

    节点查询

    先放一段测试的html代码

      <div class="outer" id="outer">
        <ul class="list list-1">
          <li class="item">list-one</li>
          <li class="item">list-two</li>
          <li class="item">list-three</li>
        </ul>
      </div>
    
      <input type="button" name="btnSubmit" value="刷新"/>
    

    常用的节点查询方法

    1. getElementById

      根据元素的id属性值进行节点查询,返回单一节点。

      document.getElementById("outer")  // <div class="outer" id="outer">......
      
    2. getElementsByClassName

      根据元素的classname属性值就行查询。

      document.getElementsByClassName("item") // HTMLCollection(3) [li.item, li.item, li.item]
      
    3. getElementsByName

      根源节点的name属性进行查询。

      document.getElementsByName("btnSubmit") // NodeList [input]
      
    4. getElementsByTagName

      根据节点标签名进行查询。

      document.getElementsByTagName("li") // HTMLCollection(3) [li.item, li.item, li.item]
      
    5. querySelector

      根绝css选择器进行节点查询,返回单个节点。

      document.querySelector("#outer") // <div class="outer" id="outer">......
      
    6. querySelectorAll

      根绝css选择器进行节点查询,返回节点列表。

      document.querySelectorAll(".item") // NodeList(3) [li.item, li.item, li.item]
      

      在没有querySelectorquerySelectorAll出现之前,基本都是通过前四个查询方法配合 childNodesparentNode方法扩展出各种方法。

    一些特殊查询属性

    • document.all 返回所有的节点
    • document.images 返回所有的图片
    • document.forms 返回所有的form表单
    • document.links 返回所有的链接标签
    • document.embeds 返回所有的 object标签元素,以前主要用于flash,pdf等等

    querySelectorAll 注意事项

    • 其返回的静态的NodeList, 随后对DOM元素的改动不会影响其集合的内容。

      下面的代码可以看到,添加一个节后后, nodeList长度并没有变化。

        <ul class="list list-1">
          <li class="item">list-one</li>
          <li class="item">list-two</li>
          <li class="item">list-three</li>
        </ul>
      
        <script>
            var  nodeList = document.querySelectorAll(".item");
            console.log("len:", nodeList.length);  // 3
      
            var liEl = document.createElement("li");
            liEl.className = "item";
            liEl.innerHTML = "list-for"
            document.querySelector(".list").appendChild(liEl);
            
            console.log("len:", nodeList.length); //3 
        </script>
      
    • querySelectorAll可能返回的不是你期望的值

      <div class="outer">
        <div class="select">
          <div class="inner">
          </div>
        </div>
      </div>
      
      <script>
      var select = document.querySelector('.select');
      var inner = select.querySelectorAll('.outer .inner');
      inner.length; // 1, not 0!
      </script>
      
      

      那么怎样才能返回期望的结果呢?答案是 :scope

      var select = document.querySelector('.select');
      var inner = select.querySelectorAll(':scope .outer .inner');
      inner.length; // 0
      
    • 转义特殊字符

        <div id="foo\bar"></div>
        <div id="foo:bar"></div>
      
        <script>
          console.log('#foo\bar')               // "#fooar"
          document.querySelector('#foo\bar')    // 不匹配任何元素
      
          console.log('#foo\\bar')              // "#foo\bar"
          console.log('#foo\\\\bar')            // "#foo\\bar"
          document.querySelector('#foo\\\\bar') // 匹配第一个div
      
          document.querySelector('#foo:bar')    // 不匹配任何元素
          document.querySelector('#foo\\:bar')  // 匹配第二个div
        </script>
      

    HTMLCollection 和 NodeList的区别

    细心的通知可能发现了,上面的方法,有的返回的是HTMLCollection,有的返回的是NodeList。 他们有什么区别呢?

    这里先要弄清晰继承关系:

    HTMLElement -> Element -> Node-> EventTarget
    

    EventTarget 前一个提供了事件分发能力,本身也是一个订阅发布中心,更多详情参见 3行代码一个订阅发布中心,不会不知道吧

    Node 有 12种节点类型,详情参见 NodeType,我们常用的 div, span等等属于nodeType=1的节点类型。

    所以:

    HTMLCollection 是元素节点类型,即nodeType为1的节点。

    NodeList 是节点集合,包含文本节点,注释节点等等其他节点。

    怎么查询伪元素

    // html代码  
    <style>
        .nihao::before{
          content: '你好,';
        }
      </style>
      <div class="nihao" id="nihao">
        Tom
      </div>
    

    答案是不能,但你可以通过 window.getComputedStyle 来获取其样式。

    window.getComputedStyle(nihao, "before")["content"] // "\"你好,\""
    

    节点删除

    先特出测试的html代码段

      <ul class="list list-1">
        <li class="item">list-one</li>
        <li class="item">list-two</li>
        <li class="item">list-three</li>
      </ul> 
    

    Node.removeNode

    这种我们用的最多的方法,前提是首先得获得要被删除元素的父节点,可以使用parentNode或者parentElement获得。

    
        var ul = document.querySelector(".list");
        console.log("li length", ul.children.length);  // 3
        ul.removeChild(ul.children[0])  // removeChild
        console.log("li length", ul.children.length); // 2
    
    

    Element.remove

    这个方法属于 Element对象上,也就表明,其他nodeType类型是不可以使用的, 其不需要获得副节点。

    
        var ul = document.querySelector(".list");
        console.log("li length", ul.children.length);  // 3
        ul.children[0].remove();  // remove
        console.log("li length", ul.children.length); // 2
    
    

    outerHTML或者innerHTML

    
       var ul = document.querySelector(".list");
        console.log("li length", ul.children.length);  // 3
        ul.children[0].outerHTML = null   // outerHTML
        console.log("li length", ul.children.length); // 2
    
    
    

    Document.adoptNode

    从其他的document文档中获取一个节点。 该节点以及它的子树上的所有节点都会从原文档删除。

    
    var ul = document.querySelector(".list");
    console.log("li length", ul.children.length);  // 3
    document.adoptNode(ul.children[0]); // adoptNode
    console.log("li length", ul.children.length); // 2
    
    

    批量删除节点

    批量删除,比如清除某个节点下的所有子节点,一般是使用while循环,暴力的方式是 innerHTML = null

    innerHTML = null可能导致事件监听器没有被取消,以导致内存泄漏,具体有么有,还得看浏览器的实现。

    我们封装一个吧:

    function clearChildNodes(node){
        while(node.hasChildNodes()){
            node.removeChild(node.firstChild);
        }
    }
    const ul = document.querySelector(".list");
    console.log("nodes:", ul.childNodes.length);  // 7
    clearChildNodes(ul);   
    console.log("nodes:", ul.childNodes.length);  // 0
    

    空白节点

    为什么是7个节点呢? 看图上的空白节点,有4个, 4+3 =7楼。

    【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

    我们调整一下代码, 删除空白,再看输出

      <ul class="list list-1"><li class="item">list-one</li><li class="item">list-two</li><li class="item">list-three</li></ul>
    

    【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

    那空白节点,究竟是个什么东西??

    看代码,其实就是nodeType为3的文本节点。进行输出的时候其textConent为空。

       var ul = document.querySelector(".list");
        console.log("li length", ul.childNodes.length);  // 7
    
        var firstNode = ul.childNodes[0];
        console.log("nodeType", firstNode.nodeType);  // 3 
        console.log("content", firstNode.textContent); // 
    

    我们不妨添加一点内容, 你就能清晰的知道了, 其childNodes长度依旧是7,第一个文本节点的内容是 text content

      <ul class="list list-1">text content
        <li class="item">list-one</li>
        <li class="item">list-two</li>
        <li class="item">list-three</li>
      </ul> 
    

    【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

    小结

    是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。

    篇幅优先,如果star超过 100, 再写一篇节点增加和更新的文章。

    写在最后

    写作不易,你的一赞一评就是我前行的最大动力。
    技术交流群,请加微信 dirge-cloud。


    起源地下载网 » 【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元