zoukankan      html  css  js  c++  java
  • DOM 文本节点 、节点列表

    一般通过文本节点的nodeValue来读取或改变文本节点中的文本。该文本节点通常是元素节点的firstChild

    var x = document.getElementById('test');
    alert(x.firstChild.nodeValue);
    x.firstChild.nodeValue = "I never hack text nodes."

    x.firstChild只在该文本节点确实是元素的第一个子节点时可以工作。如果不是那样的话,访问该文本节点会有些困难。

    <p id="test"><br/>I am a JS hacker.</p>

    现在 x.firstChild是元素节点<br/>而它没有nodeValue值。你只有通过 x.lastChild 或 x.childNodes[1]来访问该文本节点。

     

    空文本节点

    普通的文本节点很容易处理。不幸的是,还有空文本节点这样的东西。它们是最没用却烦人的W3C DOM特性。

    <body>
    <h1>Hello word!</h1>
    <p> I am a JS hacker!</p>
    </body>

    你认为<body>有多少个子节点?2个?那么你错了。<body>有5个子节点。其中有3个是空文本节点。它们是标签之间的文本,一个硬回车或空格。

     

    举例来说,看这段脚本:

    var x = document.getElementsByTagName('p')[0];

    x.parentNode.insertBefore(x,x.previousSibling)

    这看起来很简单,取得段落并把它插入到前一个兄弟节点(h1)之前。

    不幸的是,在(除Explorer外的)所有浏览器中,<p>的前一个兄弟节点不是<h1>而是</h1>与<p>之间的空文本节点。DOM树改变了,但不是按我们希望的那样

     


    一个移除这些兼容性问题的方法是去掉所有空文本节点。但这让HTML变得更让人发狂了。

    所以,空文本节点无法避免,最大的受害者是previousSibling 和 nextSibling. 

    还有childNodes[]这个节点列表充满空文本节点因而很少被用到。

     

     

    让我们试着让previousSibling能工作起啦。我们想把<p>插入到<h1>之前

    var x = document.getElementByTagName('p')[0];

    var previousElement = x.previousSibling;

    while(previousElement.nodeType == 3 )

            previousElement = previousElement.previousSbling

    x.parentNode.insertBefore(x,previousElement);

    我们取得元素的previousSibling。如果是一个文本节点,我们就在获取previousSibling的前一个兄弟节点,直到遇到一个非文本节点。

    此处有一个隐藏的假设:p的父节点决不会包含 真正文本的文本节点。如果你确信这样,这个例子就能工作。

     

    最保险的解决方案就是根本不用使用previousSibling

    var x = document.getElementsByTagName('p')[0];
    var y = document.getElementsByTagName('h1')[0];
    x.parentNode.insertBefore(x,y);

     

     

    ==================================================================================

     

    节点列表

    getElementsByTagName()是最重要的一个,让我们仔细看看节点列表和它们的危险性。

    表面上,节点列表看起来像数组。它们接受一对方括号中的索引数字,并返回该索引数的节点。

    var x = document.getElementsByTagName(‘p’)[1];

    x 是文档中的第二个段落(索引为1)

     

    所有的节点列表有一个length属性,它给出了节点列表的长度:

    var x = document.getElementsByTagName('p').length;

    x就是文档中段落的数量。

    这2个特性结合起来让我们可以把节点列表当作数组一样使用:

    var x = document.getElementsByTagName('p');

    for(var i=0;i<x.length;i++){

        //操作每一个段落

    }

     

    危险

    但是节点列表不是静态的。事实上,它们是危险的动态结构,因为它们会立即反映文档中的任何变化。

    例如,当我们遍历文档中所有<tr>或<div>标签,把它们其中拥有rel属性的元素移动到waitingRoom 中。表面上看起来这很简单。问题是当移动tr[1]的时候列表立即更新了,tr[2]变成了tr[1],脚本前进到索引[2],它永远无法检查这个<tr>

    辅助数组是一个又好又简单的解决方案。当我需要遍历一个节点列表,并从它的元素中删除一些时,我总是用这个方法。原理很简单,如果某个元素应该被删除,我就把它加入辅助数组。对节点列表的for()循环结束后,我就开始一个新的循环,遍历该数据,并从文档中把这些tr删除。

    使用辅助数组的时候,我总是使用push()的shift(),这是数组的两个方法。另外,请注意辅助数组在第二次循环后就没有存在的必要了:它已经完成了它的任务。

    var containers = document.getElementsByTagName(containerTag);

    var hiddenFields = new Array;

    for(var i=0;i<containers.length;i++){

         if(containers[i].getAttribute('rel')){

                   //做点什么

                  hiddenFields.push(containers[i]);

          //arrayObject.push(newelement1,newelement2,....,newelementX)

        //arrayObject.pop()将删除 arrayObject 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。

         }

    }

    while(hiddenFields.length){

            //其他操作,包括创建newMarker

            hiddenFields[0].parentNode.replaceChild(newMarker,hiddenFields[0]);//objDocumentNode = xmlDocumentNode.replaceChild(newChild,oldChild);

            waitingRoom.appendChild(hiddenFields.shift()); 

    }

    这段脚本会遍历所有的<tr>并且,如果某一个拥有rel属性,就把它压进辅助数组hiddenFields。在遍历完成后,hiddenFields就会包含所有指向需要被删除的tr的引用。

    然后,脚本启动一个while()循环,在一些操作后,脚本就会把tr替换成标识符,并且把它加入waitingRoom这会讲它从文档中删除,但它不会从hiddenFileds中消失。hiddenFileds毕竟是真实的数组,而不是节点列表。

    正因如此,所以脚本最后一行使用了shift() 这哥方法会返回数组中的第一个元素,并同时把它从数组中删除。因为从数组中删除了tr,所以下一个元素变成了hieenFields[0],接着循环,直到hiddenFields当中再也没有元素(即它的length为0)

  • 相关阅读:
    vue在new的时候做了什么???
    vue中关于this的指向
    jquery 的本地存储 localStorage
    解读vue实例的双向绑定源码
    node修改数据遇到的坑
    node.js邮箱验证码
    webpack基础配置
    获取时间差。
    js获取时间方法
    node的buffer转换为字符串
  • 原文地址:https://www.cnblogs.com/cuoreqzt/p/2637637.html
Copyright © 2011-2022 走看看