Javascript中的Dom概念和Node类型(一)

一、Dom的概念和节点层次

Dom:Document Object Model 文档对象模型,可以将任何 html 文档描绘成一个由多层次节点构成的结构。换而言之,就是Dom会把文档看成一棵树,同时定义很多方法来操作这棵树中的每一个元素(节点)。

文档:html 页面

文档对象:页面中的元素

文档对象模型:为了能够让程序(js)去操作页面中的元素

文档节点:文档节点是每个文档的根节点,文档节点只有一个子节点,即<html>元素,我们称为文档元素,文档元素是文档的最外层元素,文档中其他所有元素都包含在文档元素中,每个文档都只能有一个文档元素,在 html 页面中,文档元素始终是<html>元素。

二、Node类型

js中所有节点的类型都继承自 Node 类型。
共有12种类型,用12个数值来表示。

1.nodeType :返回节点的节点类型

节点类型

我们只需要注意前三种即可,其他了解就好
元素节点 : 1
属性节点 : 2
文本节点 : 3

if(someNode.nodeType  ==1){
  alert(“Node is an element!”)
}

2.nodeName 和 nodeValue

nodeName :元素的标签名
nodeValue:始终为null

if(someNode.nodeType  ==1){
  value = someNode.nodeName  //元素的标签名 
}

在这个例子中,首先检查节点类型,看它是不是一个元素,如果是,则取得nodeName的值。

三、节点关系

1.childNodes 子节点列表集合,(只读属性)

每个节点都有一个 childNodes 属性,其中保存着一个NodeList对象(类数组对象),用来保存一组有序的节点,可以通过位置来访问这些节点。
注意:
1.是对象下的一种属性
2.使用时不加括号
3.只包含一级子节点,不包含后辈孙级以下的节点
4.标准下:包含了文本和元素类型的节点,也会包含非法嵌套的子节点
5.非标准下:只包含元素类型的节点,ie7以下不会包含非法嵌套子节点

 var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes[1];
//var secondChild = someNode.childNodes.item(1);
vat count = someNode.childNodes.length;
<script>
window.onload = function() {
    var oUl = document.getElementById('ul1');
    alert( oUl.childNodes.length );
      //标准下为11,ie7以下为4(因为包括了文本节点和非法节点,ie7以下不识别)
}
</script>
<ul id="ul1" style="border: 1px solid red;">
        <li>11111</li>
        <li>22222</li>
        <li>33333</li>
        <li>44444</li>
        <p>pppppppp</p>
    </ul>

2.parentNode : 当前节点的父级节点(只读属性)

<script>
window.onload = function() {
    
    var aA = document.getElementsByTagName('a');
    
    for (var i=0; i<aA.length; i++) {
        aA[i].onclick = function() {
            this.parentNode.style.display = 'none'; 
            //当点击标签a时,li隐藏
        }
    }
    
    
}
</script>

<body>
    <ul id="ul1">
        <li>11111 <a href="javascript:;">隐藏</a></li>
        <li>22222 <a href="javascript:;">隐藏</a></li>
        <li>33333 <a href="javascript:;">隐藏</a></li>
        <li>44444 <a href="javascript:;">隐藏</a></li>
    </ul>
</body>

3.previousSibling 和 nextSibling

注意:
1.可以访问同一列表的其他节点
2.列表中的第一个节点 previousSibling 属性值为null
3.列表中最后一个节点 nextSibling 属性值为null
4.如果列表中只有一个节点,那么该节点的 previousSibling 和 nextSibling 都为null

4.firstChild : 第一个子节点 (只读属性)

lastChild:最后一个节点 (只读属性)

注意:
1.标准下:firstChild 和lastChild会包含文本类型的节点
2.非标准下:只包含元素节点
3.在只有一个节点的情况下,firstChild 和lastChild 指向同一个节点
4.如果没有子节点,firstChild 和lastChild 均为null

var oUl = document.getElementById('ul1');
    alert( oUl.firstChild );   //[object Text]  文本节点
<ul id="ul1">
        <li>11111</li>
        <li>22222</li>
        <li>33333</li>
        <li>44444</li>
    </ul>
<script>
window.onload = function() {
    
    var oUl = document.getElementById('ul1');
    
    var oFirst = oUl.firstChild;
    oFirst.style.background = 'red';

    var oLast = oUl.lastChild;
    oLast.style.background = 'yellow';
    
    var oNext = oFirst.nextSibling;
    oNext.style.background = 'blue';

    var oPrev = oLast.previousSibling;
    oPrev.style.background = 'orange';
    //结果打开页面没有变化,因为他们的操作都会基于文本节点,文本节点没有style属性,所以不会有变化
}
</script>

<body>
    <ul id="ul1">
        <li>11111</li>
        <li>22222</li>
        <li>33333</li>
        <li>44444</li>
    </ul>
</body>

解析:打开页面没有变化,因为他们的操作都会基于文本节点,文本节点没有style属性,所以不会有变化

5.hasChildNodes()

在节点包含一个或多个子节点的情况下返回true,比查询childNodes列表的length更简便

6.ownerDocument 指向表示整个文档的文档节点

表示任何节点都属于它所在的文档,任何节点都不能同时存在于两个或者更多个文档中,这个属性,可以直接访问文档节点

四、基本节点操作方法

1.appendChild(要添加的元素) [方法] 追加子元素

用于在ChildNodes列表的末尾添加一个节点,添加节点后,ChildNodes 的新增节点,父节点以及以前的最后一个节点的关系指针都会相应的得到更新。

var oUl = document.getElementById('ul1');
var oLi = document.createElement('li');     
<body>
    <input type="text" id="text1" /><input type="button" value="留言" id="btn" />
    <ul id="ul1"></ul>
</body>

结果如下图:


appendChild

2.insertBefore(新的元素,被插入的元素) [方法]

将节点放在某个特定的位置

<script>
window.onload = function() {

    var oUl = document.getElementById('ul1');
    var oLi = document.createElement('li');
    oUl.insertBefore( oLi, oUl.children[0] );
    
}
</script>

<body>
    <ul id="ul1">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>

结果如图所示


insertBefore

3.replaceChild(要插入的节点,被替换节点) 替换子节点 [方法]

要替换的节点将这个方法返回并从文档树中删除,同时由要插入的节点占据其位置

<script>
window.onload = function() {
    
    var oDiv = document.getElementById('div1');
    var oBtn = document.getElementById('btn');
    var oP = document.getElementById('p1');
    oBtn.onclick = function() {

        document.body.replaceChild( oDiv, oP );
    //当点击按钮后,p标签被div标签替换
    }
    
}
</script>

<body>
    <div id="div1">div1</div>
    <input type="button" value="按钮" id="btn" />
    <hr />
    <p id="p1">ppppp</p>
</body>

removeChild(要删除的元素); 删除元素 [方法]

被移除的节点称为该方法的返回值

<script>
window.onload = function() {

    var oUl = document.getElementById('ul1');
    var oLi = document.getElementsByTagName('li')[0];
    var child = oUl.removeChild( oLi);
        
}
</script>

<body>
    <ul id="ul1">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>

结果如图:


removeChild

五、其他操作方法

1.cloneNode()用于创建调用这个方法的节点的一个完全相同的副本 [方法]

该方法接收一个布尔值参数,表示是否执行深复制
参数为true,执行深复制,即复制节点及整个子节点树
参数为false,执行浅复制,即只复制该节点本身

<script>
window.onload = function() {

    var oUl = document.getElementById('ul1');
    
    var deepList = oUl.cloneNode(true);
    alert(deepList.childNodes.length);  //7

    var shallowList = oUl.cloneNode(false);
    alert(shallowList.childNodes.length);  //0
        
}
</script>

<body>
    <ul id="ul1">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>

2.normalize(),处理文档树中的文本节点

当由于解析器的实现或Dom操作等原因,可能会出现文本节点不包括文本,或者接连出现两个文本节点的情况,当在某个节点上调用该方法时,就会在该节点的后代节点上查找上述两种情况,如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。

推荐阅读更多精彩内容