Skip to content

Node类型

所有的元素都继承于Node类型

1、属性

javascript

// Node是DOM中的一个接口  所有的元素都继承于他

interface Node {

    // NodeType  节点的类型
    const unsigned short ELEMENT_NODE = 1;
    // 属性类型节点
    const unsigned short ATTRIBUTE_NODE = 2;
    // 文本类型节点
    const unsigned short TEXT_NODE = 3;
    // CDATA节点
    const unsigned short CDATA_SECTION_NODE = 4;
    // 实体引用名称节点
    const unsigned short ENTITY_REFERENCE_NODE = 5;
    // 实体名称节点
    const unsigned short ENTITY_NODE = 6;
    // 处理指令节点 
    const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
    // 注释节点
    const unsigned short COMMENT_NODE = 8;
    // 文档节点
    const unsigned short DOCUMENT_NODE = 9;
    // 文档类型节点
    const unsigned short DOCUMENT_TYPE_NODE = 10;
    // 文档片段节点
    const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
    // DTD声明节点
    const unsigned short NOTATION_NODE = 1  
    
    // 返回节点的名称
    readonly attribute DOMString nodeName;
    
    // nodeValue属性返回或设置当前节点的值,格式为字符串
             attribute DOMString nodeValue;
            
    // raises(DOMException) on setting
    // raises(DOMException) on retriev  
    返回节点的类型
    readonly attribute unsigned short nodeType;
    // 返回节点的父节点 如果没有则为null
    readonly attribute Node parentNode;
    // 返回节点的子节点 NodeList
    readonly attribute NodeList childNodes;
    // 返回节点的第一个子节点(可能为文本节点),没有返回null
    readonly attribute Node firstChild;
    // 返回节点的最后一个子节点(可能包含文本节点),没有返回null
    readonly attribute Node lastChild;
    // 返回节点的上一个节点(可能包含文本节点),没有返回null
    readonly attribute Node previousSibling;
    // 返回节点的下一个节点(可能包含文本节点),没有返回null
    readonly attribute Node nextSibling;
    // 返回节点的属性NamedNodeMap
    readonly attribute NamedNodeMap attributes;
    // Modified in DOM Level 2:
    // 返回节点的document节点
    readonly attribute Document ownerDocument;
    // Modified in DOM Level 3:
    
    //节点操作
    // 在节点的 指定子节点前插入一个节点(为null则 === appendChild())
    Node insertBefore( in Node newChild, in Node refChild)
    raises(DOMException);
    // Modified in DOM Level 3:
    // 用一个节点替换节点指定的子节点
    Node replaceChild( in Node newChild, in Node oldChild)
    raises(DOMException);
    // Modified in DOM Level 3:
    // 删除节点指定的子节点
    Node removeChild( in Node oldChild)
    raises(DOMException);
    // Modified in DOM Level 3:
    // 在节点末尾添加一个子节点
    Node appendChild( in Node newChild)
    raises(DOMException);
    // 判断节点是否包含子节点 === (node.firstNode === null) || (node.lastNode === null) === (node.childNodes.length === 0)
    boolean hasChildNodes();
    // 克隆指定的节点
    Node cloneNode( in boolean deep);
    // Modified in DOM Level 3:
    void normalize();
    // Introduced in DOM Level 2:
    boolean isSupported( in DOMString feature, in DOMString version);
    // Introduced in DOM Level 2:
    readonly attribute DOMString namespaceURI;
    // Introduced in DOM Level 2:
    attribute DOMString prefix;
    // raises(DOMException) on setti    // Introduced in DOM Level 2:
    readonly attribute DOMString localName;
    // Introduced in DOM Level 2:
    boolean hasAttributes();
    // Introduced in DOM Level 3:
    readonly attribute DOMString baseUR // DocumentPosition
    const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
    const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
    const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
    const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
    const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
    const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x2    // Introduced in DOM Level 3:
    unsigned short compareDocumentPosition( in Node other)
    raises(DOMException);
    // Introduced in DOM Level 3:
    attribute DOMString textContent;
    // raises(DOMException) on setting
    // raises(DOMException) on retriev  // Introduced in DOM Level 3:
    boolean isSameNode( in Node other);
    // Introduced in DOM Level 3:
    DOMString lookupPrefix( in DOMString namespaceURI);
    // Introduced in DOM Level 3:
    boolean isDefaultNamespace( in DOMString namespaceURI);
    // Introduced in DOM Level 3:
    DOMString lookupNamespaceURI( in DOMString prefix);
    // Introduced in DOM Level 3:
    boolean isEqualNode( in Node arg);
    // Introduced in DOM Level 3:
    DOMObject getFeature( in DOMString feature, in DOMString version);
    // Introduced in DOM Level 3:
    DOMUserData setUserData( in DOMString key, in DOMUserData data, in UserDataHandler handler);
    // Introduced in DOM Level 3:
    DOMUserData getUserData( in DOMString key);
};

1.1、 nodeType

所有的节点都存在一个nodeType属性,此表明节点的类型 (一共12种 )

// 常用的4种
Node.ELEMENT_NODE   === 1
Node.ATTRIBUTE_NODE   === 2
Node.TEXT_NODE  === 3
Node.DOCUMENT_NODE === 9
栗子:
javascript
var node = document;
console.log(node.nodeType);    // 9 document 类型
console.log(node.nodeName);    // #document
console.log(node.nodeValue);    // null

var div1 = document.getElementById('div1');
console.log(div1.nodeType)   //1  element元素类型
console.log(div1.nodeName)   //1  DIV
console.log(div1.nodeValue)   //  null

var text = div1.childNodes;
console.log(text[0].nodeType);     // 3  text类型
console.log(text[0].nodeName);     // #text
console.log(text[0].nodeValue);     // text

var input1 = document.getElementById('input');
console.log(input1.nodeType)   //1  element元素类型
console.log(input1.nodeName)   //1  INPUT
console.log(input1.nodeValue)   //  null

1.2、Node.nodeName,Node.nodeValue

一般只关注于元素类型 对于元素类型 nodeName保存的是元素的类型名称,nodeValue为null

节点访问属性

image

1. Element.parentNode 获取元素的父节点
2. Element.nextSibling、 Element.previousSibling,获取元素紧随其后的同辈节点,还有之前的同辈节点。
3. Element.firstChild、Element.lastChild 获取元素的第一个跟最后一个节点。
4. Element.childNodes 返回元素的所有子节点(NodeList)

1.3、Node.childNodes(只读 属性 子节点列表集合 动态改变)(不建议使用 Node.children代替)

返回的是元素的子节点,其为NodeList对象(类数组)

image

image

在chrome下面返回的是却是 5个节点

<font class="j-font-red j-font-blod" >注:</font>

a) 在chrome、firefox、opera、ie9+ 都是返回5个节点 在IE8-返回3个节点。(回车也作为一个text节点元素)

b) 动态改变

image

c) IE7一下,不包含非法嵌套的子元素;其他浏览器包含非法嵌套子元素。

1.4 Node.children

1.5 Node.firstChild,Node.lastChild

栗子:
// firstChild跟childNodes一样存在兼容性问题  在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点
console.log(ul.firstChild); //  在firefox下是#text
console.log(ul.firstChild.nodeName); //  在firefox下是#text  在 IE8及以下  返回的是li
//没有子节点 返回null
console.log(div1.firstChild); //null

// lastChild  跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点
// 在IE8 下返回的是  DIV
// 在IE7 下返回的是  LI
console.log(ul.lastChild);
console.log(ul.lastChild.nodeName);
//没有子节点 返回null
console.log(div1.lastChild); //null
Element.firstChild
作用: 返回当前元素的第一个子节点,如果没有子节点返回null
注意: 1、firstChild跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点。
Element.lasetChild
作用: 返回当前节点的最后一个子节点。如果没有子节点,则返回 null。
注意: 1、lasetChild跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点。

1.6 Node.nextSibling,Node.previousSibling

栗子:

//  nextSibling  返回其父节点的 childNodes 列表中紧跟在其后面的节点,如果指定的节点为最后一个节点,则返回 null。
//  注:跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点

console.log(li1.nextSibling); // emptyTextNode  空文本节点
console.log(li1.nextSibling.nextSibling); // li2   
// 没有同辈紧跟在其后面的节点  返回null
console.log(li3.nextSibling.nextSibling.nextSibling.nextSibling); // null

//  previousSibling  返回当前节点的前一个兄弟节点,没有则返回null。
//  注:跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点
console.log(li1.previousSibling); // emptyTextNode  空文本节点
// 没有同辈紧跟在其后面的节点  返回null
console.log(li1.previousSibling.previousSibling); // null
Element.nextSibling
作用: 返回其父节点的 childNodes 列表中紧跟在其后面的节点,如果指定的节点为最后一个节点,则返回 null。
注意: 1、nextSibling跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点。
Element.previousSibling
作用: 返回当前节点的前一个兄弟节点,没有则返回null。
注意: 1、previousSibling跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点。

1.7 Node.parentNode

栗子:
// element.parentNode  返回指定的节点在DOM树中的父节点.
// 注 : 一个元素的父节点 可能是一个Element元素节点,可能是一个Document文档节点,当然也有一个是一个DocumentFragment文档碎片节点
console.log(li1.parentNode); //ul
console.log(document.parentNode); //null
console.log(document.firstChild.parentNode) // HTMLDocument

var documentFragment = document.createDocumentFragment('div');
var documentFragmentChild = document.createElement("div")
documentFragmentChild.innerHTML = '文档碎片节点';
documentFragment.appendChild(documentFragmentChild);
//没有插入到DOM树中  返回就是一个DocumentFragment虚拟DOM节点
console.log(documentFragmentChild.parentNode); //DocumentFragment
// 插入到DOM树中  返回就是真实的DOM元素节点了
div1.appendChild(documentFragment);
console.log(documentFragmentChild.parentNode); //div1元素
Element.parentNode
作用: 返回指定的节点在DOM树中的父节点(一个元素节点的父节点可能是一个元素(Element )节点,也可能是一个文档(Document )节点,或者是个文档碎片(DocumentFragment)节点)。

1.7 Node.ownerDocument

栗子:
// ownerDocument 返回当前节点的顶层document对象

console.log(ul.ownerDocument) // #document
Element.ownerDocument
作用: 会返回当前节点的顶层的 document 对象。

2. 方法

节点操作方法

2.1 Node.appendChild()

作用 : 将一个节点添加到指定父节点的子节点列表的末尾。
var child = node.appendChild(child);    //node 需要插入节点的父节点
入参: 子节点
出参: 插入的子节点
栗子:
var createEle = document.createElement("div");
createEle.setAttribute('class', 'childClass');
createEle.innerText = '这是appendChild的节点';

div1.appendChild(createEle); //插入子节点
// 如果child节点已存在 则那个节点会首先从原先的位置移除,然后再插入到新的位置。(保留可用cloneNode())
var appendChildEle = document.getElementsByClassName('appendChild')[0];
div1.appendChild(appendChildEle);   //原来的节点 从DOM树中移除了

2.2 Node.insertBefore()

作用 : 在参考节点之前插入一个节点作为父节点的子节点尾。
javascript
var child = node.insertBefore(child,referenceEle);
入参 : child : 需要插入的子节点
     referenceEle : 参考位置节点,不能为undefined 如果没有参考节点,入参为null
出参: 返回插入的子节点 child
注意:
1. 如果referenceEle为null则跟appendChild()一样在子节点末尾插入节点。
2. 如果插入的节点child已存在于DOM树中 则会先从原先的位置移除,然后再插入到新的位置。
栗子:
javascript
var createEle = document.createElement("div");
createEle.setAttribute('class', 'childClass');
createEle.innerText = '这是appendChild的节点';
// 插入一个新的节点
var insertChild = div1.insertBefore(createEle,document.getElementById("child3"));
//在子节点末尾插入新节点   null 而不是  div1.insertBefore(createEle);
var insertChild3 = div1.insertBefore(createEle,null);
//插入一个已存在的节点
var insertChild2 = div1.insertBefore(document.getElementsByClassName('appendChild')[0],document.getElementById("child3"));

2.3 Node.removeChild()

作用 : 从DOM中删除一个节点指定的子节点,并返回删除的节点。
javascript
 var child = node.removeChild(child);
入参 : child : 删除的子节点Node
出参: 返回删除的子节点 child
注意:
1. 被删除的子节点仍然保存在内存中,可以从新加入到DOM中。除非被回收了。
2. 如果child不是node的子节点,或者是其孙节点都抛出异常。
栗子:
javascript
var removeChildEle = div1.removeChild(document.getElementById('child3'));
// var removeChildEle = div1.removeChild(document.getElementById('child3'));  //报错

// 删除的节点不是其子节点
// Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
// var removeChildEle1 = div1.removeChild(document.getElementById('div2'));   //报错
// 删除的节点是他的孙节点  报错
// Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
var removeChildEle2 = div1.removeChild(document.getElementById('child4'));   //报错

2.4 Node.replaceChild()

作用 : 用指定的节点替换当前节点的一个子节点,返回替换掉的子节点。
var replaceChildNode = node.replaceChild(newChild,replaceChildNode);
入参 : newChild : 替换的节点
     replaceChildNode : 被替换的子节点.
出参: 返回被替换的子节点
栗子:
javascript
//div2节点替换了  子节点1
var replaceChildNode = div1.replaceChild(document.getElementById('div2'),div1.firstChild.nextSibling);  

// 替换的节点不是其子节点,报错
// TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node'
var replaceChildNode1 = div1.replaceChild(document.getElementById('div2'),null);  //报错

// Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
var replaceChildNode2 = div1.replaceChild(document.getElementById('div2'),document.getElementById('child4'));

2.5 Node.cloneNode()

作用 : 返回调用该方法的节点的一个副本。
javascript
var clonedNode = node.cloneNode(true/false);
入参 : false (默认) : 只克隆节点本身 着意味着包含在被复制节点里的所有文本将不会被复制,但是属性节点会被复制:
     true : 深度克隆,克隆节点及其所有的后代节点
出参: 返回被克隆节点的一个副本
注意:
1. 如果被复制元素有一个独一无二的id属性,千万不要忘记对复制出来的新元素的id属性进行修改,在同一个文档里面,不同元素的id属性值必须各不相同。
栗子:
javascript
var cloneDiv = div1.cloneNode();
console.log(cloneDiv);
//没有克隆元素的子节点和文本节点  <div id="div1" style="background-color: red;"></div>
document.getElementById('div2').appendChild(cloneDiv);

var cloneDivTrue = div1.cloneNode(true);
// 节点及其所有的后代都克隆了 <div id="div1" style="background-color: red;"><div>子节点1</div><div>子节点2<span id="child4"></span></div><div id="child3">子节点3</div></div>
console.log(cloneDivTrue);
document.getElementById('div2').appendChild(cloneDivTrue);

2.6 Node.hasChildNodes()

作用 :返回当前节点是否包含子节点,返回Boolean
javascript
var boolean = node.hasChildNodes();
出参: 返回是否有子节点
注意:
1.跟childNodes一样存在兼容性问题 在IE8即以下不计算元素间的空文本节点,在高级浏览器下计算空白节点。
栗子:
javascript
console.log(document.getElementById("div2").hasChildNodes());    //true  

//判断元素是否存在子节点方法
// 1. document.getElementById("div2").hasChildNodes() === true
// 2. document.getElementById("div2").childNodes.length === 0
// 3. document.getElementById("div2").firstChild === null

// *4. document.getElementById("div2").children.length ===0  // 这个跟上面不一样就是  空文本节点

2.7 Node.contains()

作用 : 判断入参节点是否是其--后代节点
javascript
 var boolean = node.contains(descendantNode);
入参 : 判断的节点
出参: 是否是后代节点
注意:
1. 判断的是节点,而不是字符串...
栗子:
javascript
console.log(div1.contains(document.getElementById("child3"))); //true 
console.log(div1.contains(document.getElementById("child4"))); //true 
console.log(div1.contains(document.getElementById("div2"))); //false