zoukankan      html  css  js  c++  java
  • 变态的节点集合

    今天想实现jQuery的unwrap效果,换言之,就是用其孩子把其父节点干掉。为了效率,用到文档碎片,而取孩子时使用到childNodes(返回一个nodeList)

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta content="IE=8" http-equiv="X-UA-Compatible"/>
        <title>节点集合 by 司徒正美 </title>
        <style>
          #aaa {
            padding:10px;
            border:1px solid red;
          }
          p {
            border:1px solid blue;
          }
        </style>
        <script type="text/javascript">
          window.onload = function(){
            var d = document.createDocumentFragment();
            var div = document.getElementById("aaa");
            var c = div.childNodes;
            for(var i=0,n=c.length;i<n;i++){
              alert(c[i] + "  "+ i)
              d.appendChild(c[i])
            }
            div.parentNode.replaceChild(d,div)
          }
        </script>
    
      </head>
      <body>
    
        <div id="aaa">
          <p class="aaaa">司徒正美</p>
          <p class="aaaa">司徒正美</p>
          <p class="aaaa">司徒正美</p>
          <p class="aaaa">司徒正美</p>
          <p class="aaaa">司徒正美</p>
        </div>
      </body>
    </html>
    

    如果预先将nodeList转换为数组就没有问题!

          window.onload = function(){
            var d = document.createDocumentFragment();
            var div = document.getElementById("aaa");
            var c = div.childNodes;
            var arr = [];
            for(var i=0,n=c.length;i<n;i++){
              arr.push(c[i])
            }
            for(var i=0,n=arr.length;i<n;i++){
              alert(arr[i] + "  "+ i)
              d.appendChild(arr[i])
            }
            div.parentNode.replaceChild(d,div)
          }
    

    很显然nodeList还一些奇怪的特性是数组没有的。从运行框2中,我们可以看到把节点appendChild到文档碎片时,其实会把它从DOM树中剥离出来,nodeList一定是跟踪这变化,动态改变了它自身,而直线递加的i是无法对应正确的节点的索引!因此我们每次取得它的firstChild就行了。

          window.onload = function(){
            var d = document.createDocumentFragment();
            var div = document.getElementById("aaa");
            var c = div.childNodes;
            while(c.length)  d.appendChild(c[0])//每次只取它第一个节点,直到取空
            div.parentNode.replaceChild(d,div)
          }
    

    顺便一提,由getElementsByTagName取得的HTMLCollection也是这个样子,因此处理这类节点集合要打起十二分精神了!

    这两种节点集合在各浏览器还实现得不太一样,如标准浏览器我们可以用Array.prototype.slice.call将它们转换为原生数组,IE则报错。标准浏览器的它们有hasOwnProperty与valueOf,而IE是没有的……

  • 相关阅读:
    IntentService源码分析
    startService过程源码分析
    洛谷P3300 城市规划
    agc033
    洛谷P3306 随机数生成器
    洛谷P3299 保护出题人
    洛谷P3298 泉
    洛谷P3296 刺客信条
    树hash
    我们都爱膜您退火!
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1689475.html
Copyright © 2011-2022 走看看