--- title: Node slug: Web/API/Node tags: - API - DOM - Interface - Node - Reference - 参考 translation_of: Web/API/Node --- <p>{{APIRef("DOM")}}</p> <p><span class="seoSummary"><strong><code>Node</code></strong> 是一个接口,各种类型的 DOM API 对象会从这个接口继承。它允许我们使用相似的方式对待这些不同类型的对象;比如, 继承同一组方法,或者用同样的方式测试。</span></p> <p>以下接口都从 <code>Node</code> 继承其方法和属性:</p> <div>{{DOMxRef("Document")}}, {{DOMxRef("Element")}}, {{DOMxRef("Attr")}}, {{DOMxRef("CharacterData")}} (which {{DOMxRef("Text")}}, {{DOMxRef("Comment")}}, and {{DOMxRef("CDATASection")}} inherit), {{DOMxRef("ProcessingInstruction")}}, {{DOMxRef("DocumentFragment")}}, {{DOMxRef("DocumentType")}}, {{DOMxRef("Notation")}}, {{DOMxRef("Entity")}}, {{DOMxRef("EntityReference")}}</div> <p>在方法和属性不相关的特定情况下,这些接口可能返回 <code>null</code>。它们可能会抛出异常 - 例如,当将子节点添加到不允许子节点存在的节点时。</p> <p>{{InheritanceDiagram}}</p> <h2 id="属性">属性</h2> <p>从其父类型 <em>{{DOMxRef("EventTarget")}}</em><sup>[1]</sup> 继承属性。</p> <dl> <dt>{{DOMxRef("Node.baseURI")}}{{ReadOnlyInline}}</dt> <dd>返回一个表示base URL的{{DOMxRef("DOMString")}}。不同语言中的base URL的概念都不一样。 在HTML中,base URL表示协议和域名,以及一直到最后一个'/'之前的文件目录。</dd> </dl> <dl> <dt>{{DOMxRef("Node.baseURIObject")}} {{Non-standard_inline}}</dt> <dd>(不适用于网页内容) 只读的 {{ Interface("nsIURI") }} 对象表示元素的base URI.</dd> <dt>{{DOMxRef("Node.childNodes")}}{{ReadOnlyInline}}</dt> <dd>返回一个包含了该节点所有子节点的实时的{{DOMxRef("NodeList")}}。{{DOMxRef("NodeList")}} 是动态变化的。如果该节点的子节点发生了变化,{{DOMxRef("NodeList")}}对象就会自动更新。 </dd> <dt>{{DOMxRef("Node.firstChild")}} {{ReadonlyInline}}</dt> <dd>返回该节点的第一个子节点{{DOMxRef("Node")}},如果该节点没有子节点则返回<code>null</code>。</dd> <dt>{{DOMxRef("Node.isConnected")}}{{ReadOnlyInline}}</dt> <dd>返回一个布尔值用来检测该节点是否已连接(直接或者间接)到一个上下文对象上,比如通常DOM情况下的{{DOMxRef("Document")}}对象,或者在shadow DOM情况下的{{DOMxRef("ShadowRoot")}}对象。</dd> <dt>{{DOMxRef("Node.lastChild")}} {{ReadonlyInline}}</dt> <dd>返回该节点的最后一个子节点{{DOMxRef("Node")}},如果该节点没有子节点则返回<code>null</code>。</dd> <dt>{{DOMxRef("Node.nextSibling")}} {{ReadonlyInline}}</dt> <dd>返回与该节点同级的下一个节点 {{DOMxRef("Node")}},如果没有返回<code>null</code>。</dd> <dt>{{DOMxRef("Node.nodeName")}} {{ReadonlyInline}}</dt> <dd>返回一个包含该节点名字的{{DOMxRef("DOMString")}}。节点的名字的结构和节点类型不同。比如{{DOMxRef("HTMLElement")}}的名字跟它所关联的标签对应,就比如{{DOMxRef("HTMLAudioElement")}}的就是 <code>'audio'</code> ,{{DOMxRef("Text")}}节点对应的是 <code>'#text'</code> 还有{{DOMxRef("Document")}}节点对应的是 <code>'#document'</code>。</dd> <dt>{{DOMxRef("Node.nodeType")}}{{ReadonlyInline}}</dt> <dd>返回一个与该节点类型对应的<code>无符号短整型</code>的值,可能的值如下: <table class="standard-table"> <tbody> <tr> <th scope="col">Name</th> <th scope="col">Value</th> </tr> <tr> <td><code>ELEMENT_NODE</code></td> <td><code>1</code></td> </tr> <tr> <td><code>ATTRIBUTE_NODE</code> {{Deprecated_Inline}}</td> <td><code>2</code></td> </tr> <tr> <td><code>TEXT_NODE</code></td> <td><code>3</code></td> </tr> <tr> <td><code>CDATA_SECTION_NODE</code></td> <td><code>4</code></td> </tr> <tr> <td><code>ENTITY_REFERENCE_NODE</code> {{Deprecated_Inline}}</td> <td><code>5</code></td> </tr> <tr> <td><code>ENTITY_NODE</code> {{Deprecated_Inline}}</td> <td><code>6</code></td> </tr> <tr> <td><code>PROCESSING_INSTRUCTION_NODE</code></td> <td><code>7</code></td> </tr> <tr> <td><code>COMMENT_NODE</code></td> <td><code>8</code></td> </tr> <tr> <td><code>DOCUMENT_NODE</code></td> <td><code>9</code></td> </tr> <tr> <td><code>DOCUMENT_TYPE_NODE</code></td> <td><code>10</code></td> </tr> <tr> <td><code>DOCUMENT_FRAGMENT_NODE</code></td> <td><code>11</code></td> </tr> <tr> <td><code>NOTATION_NODE</code> {{Deprecated_Inline}}</td> <td><code>12</code></td> </tr> </tbody> </table> </dd> <dt>{{DOMxRef("Node.nodeValue")}}</dt> <dd>返回或设置当前节点的值。</dd> <dt>{{DOMxRef("Node.ownerDocument")}} {{readonlyInline}}</dt> <dd>返回这个元素属于的 {{DOMxRef("Document")}}对象 。 如果没有Document对象与之关联,返回null。</dd> <dt>{{DOMxRef("Node.parentNode")}} {{readonlyInline}}</dt> <dd>返回一个当前节点 {{DOMxRef("Node")}}的父节点 。如果没有这样的节点,比如说像这个节点是树结构的顶端或者没有插入一棵树中, 这个属性返回null。</dd> <dt>{{DOMxRef("Node.parentElement")}} {{readonlyInline}}</dt> <dd>返回一个当前节点的父节点 {{DOMxRef("Element")}} 。 如果当前节点没有父节点或者说父节点不是一个元素({{DOMxRef("Element")}}), 这个属性返回null。</dd> <dt>{{DOMxRef("Node.previousSibling")}} {{readonlyInline}}</dt> <dd>返回一个当前节点同辈的前一个节点( {{DOMxRef("Node")}}) ,或者返回null(如果不存在这样的一个节点的话)。</dd> <dt>{{DOMxRef("Node.textContent")}}</dt> <dd>返回或设置一个元素内所有子节点及其后代的文本内容。</dd> </dl> <h3 id="废弃的属性">废弃的属性</h3> <dl> <dt>{{DOMxRef("Node.localName")}} {{obsolete_inline}}{{readonlyInline}}</dt> <dd>返回一个表示元素名称的本土化表示方法的 {{DOMxRef("DOMString")}} 。 <div class="blockIndicator note"> <p><strong>Note:</strong> 在Firefox 3.5以及更早的版本中, HTML 元素的 localName 属性的返回值都是大写的(XHTML 例外)。在后续版本中,这种情况就不存在了。无论是 HTML 还是 XHTML 中,均返回小写的 localName。</p> </div> </dd> <dt>{{DOMxRef("Node.namespaceURI")}} {{obsolete_inline}}{{readonlyInline}}</dt> <dd>该节点命名空间的<code>URL</code>,如果没有命名空间则为<code>null</code>。 <div class="blockIndicator note"> <p><strong>Note:</strong> 在Firefox 3.5以及更早的版本中, HTML 的元素都没有命名空间. 而在最新的版本中, 无论是 HTML 还是 XML 文档树 ,所有元素的命名空间统一为 <code><a class="linkification-ext external" href="https://www.w3.org/1999/xhtml/">http://www.w3.org/1999/xhtml/</a></code>。</p> </div> </dd> <dt>{{DOMxRef("Node.nodePrincipal")}} {{Non-standard_inline}}{{Obsolete_Inline("gecko46")}}</dt> <dd>返回节点优先级 {{Interface("nsIPrincipal")}} 。</dd> <dt>{{DOMxRef("Node.prefix")}} {{Obsolete_Inline}}{{ReadOnlyInline}}</dt> <dd>返回一个节点命名空间的前缀 {{DOMxRef("DOMString")}} , 当前缀不存在时返回 <code>null</code> 。</dd> <dt>{{DOMxRef("Node.rootNode")}} {{Obsolete_Inline}}{{ReadOnlyInline}}</dt> <dd>返回一个DOM 树中顶层节点的 {{DOMxRef("Node")}} 对象,如果顶层节点不DOM 树中,则返回当前节点。该属性已被 {{DOMxRef("Node.getRootNode()")}} 方法所代替。</dd> </dl> <h2 id="方法">方法</h2> <p>从其父类型 <em>{{DOMxRef("EventTarget")}}</em><sup>[1]</sup> 继承方法。</p> <dl> <dt>{{DOMxRef("Node.appendChild()")}}</dt> <dd>将指定的 childNode 参数作为最后一个子节点添加到当前节点。<br> 如果参数引用了 DOM 树上的现有节点,则节点将从当前位置分离,并附加到新位置。</dd> <dt>{{DOMxRef("Node.cloneNode()")}}</dt> <dd>克隆一个 {{DOMxRef("Node")}},并且可以选择是否克隆这个节点下的所有内容。默认情况下,节点下的内容会被克隆。</dd> <dt>{{DOMxRef("Node.compareDocumentPosition()")}}</dt> <dd>比较当前节点与文档中的另一节点的位置。</dd> <dt>{{DOMxRef("Node.contains()")}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 布尔值,来表示传入的节点是否为该节点的后代节点。</dd> <dt>{{DOMxRef("Node.getRootNode()")}}</dt> <dd>返回上下文对象的根节点。如果shadow root节点存在的话,也可以在返回的节点中包含它。</dd> <dt>{{DOMxRef("Node.hasChildNodes()")}}</dt> <dd>返回一个{{jsxref("Boolean")}} 布尔值,来表示该元素是否包含有子节点。</dd> <dt>{{DOMxRef("Node.insertBefore()")}}</dt> <dd>在当前节点下增加一个子节点 {{DOMxRef("Node")}},并使该子节点位于参考节点的前面。</dd> <dt>{{DOMxRef("Node.isDefaultNamespace()")}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 类型值。接受一个命名空间 URI 作为参数,当参数所指代的命名空间是默认命名空间时返回 true,否则返回 false。</dd> <dt>{{DOMxRef("Node.isEqualNode()")}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 类型值。当两个 node 节点为相同类型的节点且定义的数据点匹配时(即属性和属性值相同,节点值相同)返回 true,否则返回 false。</dd> <dt>{{DOMxRef("Node.isSameNode()")}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 类型值。返回这两个节点的引用比较结果。</dd> <dt>{{DOMxRef("Node.lookupPrefix()")}}</dt> <dd>返回包含参数 URI 所对应的命名空间前缀的 {{DOMxRef("DOMString")}},若不存在则返回 null。如果存在多个可匹配的前缀,则返回结果和浏览器具体实现有关。</dd> <dt>{{DOMxRef("Node.lookupNamespaceURI()")}}</dt> <dd>接受一个前缀,并返回前缀所对应节点命名空间 URI 。如果 URI 不存在则返回 null。传入 null 作为 prefix 参数将返回默认命名空间。</dd> <dt>{{DOMxRef("Node.normalize()")}}</dt> <dd>对该元素下的所有文本子节点进行整理,合并相邻的文本节点并清除空文本节点。</dd> <dt>{{DOMxRef("Node.removeChild()")}}</dt> <dd>移除当前节点的一个子节点。这个子节点必须存在于当前节点中。</dd> <dt>{{DOMxRef("Node.replaceChild()")}}</dt> <dd>对选定的节点,替换一个子节点 {{DOMxRef("Node")}} 为另外一个节点。</dd> </dl> <h3 id="废弃的方法">废弃的方法</h3> <dl> <dt>{{DOMxRef("Node.getFeature()")}} {{obsolete_inline}}</dt> <dt>{{DOMxRef("Node.getUserData()")}} {{obsolete_inline}}</dt> <dd>允许用户从节点的 {{DOMxRef("DOMUserData")}} 获得数据。</dd> <dt>{{DOMxRef("Node.hasAttributes()")}} {{obsolete_inline}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 指定该元素是否存在某一属性。</dd> <dt>{{DOMxRef("Node.isSupported()")}} {{obsolete_inline}}</dt> <dd>返回一个 {{jsxref("Boolean")}} 类型值,指定了当前 DOM 实现是否实现了某个规范所规定功能和该功能是否被规范所规定的的节点所支持。</dd> <dt>{{DOMxRef("Node.setUserData()")}} {{obsolete_inline}}</dt> <dd>允许用户在一个节点上设置或移除 {{DOMxRef("DOMUserData")}} 。</dd> </dl> <h2 id="例子">例子</h2> <h3 id="移除某个节点的所有子节点">移除某个节点的所有子节点</h3> <pre class="brush: js notranslate">function removeAllChildren(element){ while(element.firstChild){ element.removeChild(element.firstChild); } }</pre> <h4 id="使用示例">使用示例</h4> <pre class="brush: js; notranslate">/* ... an alternative to document.body.innerHTML = "" ... */ removeAllChildren(document.body);</pre> <h3 id="遍历所有子节点">遍历所有子节点</h3> <p>下面这个函数使用递归的方式遍历一个节点的所有子节点(包括这个根节点自身)。</p> <pre class="brush: js; notranslate">function eachNode(rootNode, callback){ if(!callback){ var nodes = []; eachNode(rootNode, function(node){ nodes.push(node); }); return nodes; } if(false === callback(rootNode)) return false; if(rootNode.hasChildNodes()){ var nodes = rootNode.childNodes; for(var i = 0, l = nodes.length; i < l; ++i) if(false === eachNode(nodes[i], callback)) return; } }</pre> <h4 id="语法">语法</h4> <pre class="syntaxbox notranslate">eachNode(rootNode, callback);</pre> <h4 id="描述">描述</h4> <p>使用递归的方式对 <code>rootNode</code> 的所有后代节点执行回调函数(包括 <code>rootNode</code> 自身)</p> <p>如果没有设定 <code>callback</code>,这函数会返回一个{{jsxref("Array")}},包含 <code>rootNode</code> 和它的所有后代节点。</p> <p>如果设定了 <code>callback</code>(回调函数),如果回调函数在调用中返回 {{jsxref("Boolean")}} <code>false</code>,则当前层级的遍历会中止,同时恢复上一层级的遍历。这个可以用来在找到需要的节点之后中断循环(比如用来查找包含指定文本的文本节点)</p> <h4 id="参数">参数</h4> <dl> <dt><code>rootNode</code></dt> <dd>需要进行后代节点遍历的 <code>Node</code> 对象。</dd> <dt><code>callback</code></dt> <dd>一个可选的回调<a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function">函数</a>,接受一个节点作为唯一参数。如果没有设定, <code>eachNode</code> 返回一个包含了 <code>rootNode</code> 所有后代节点以及 <code>rootNode</code> 自身的{{jsxref("Array")}}</dd> </dl> <h4 id="使用示例_2">使用示例</h4> <p>下述例子会打印出ID为 <code>"box"</code> 的 <code><div></code> 标签内的所有 <code><span></code> 标签的 <a href="/en-US/docs/Web/API/Node/textContent"><code>textContent</code></a> 属性:</p> <pre class="brush: html; notranslate"><div id="box"> <span>Foo</span> <span>Bar</span> <span>Baz</span> </div></pre> <pre class="brush: js; notranslate">var box = document.getElementById("box"); eachNode(box, function(node){ if(null != node.textContent){ console.log(node.textContent); } });</pre> <p>用户终端上会显示如下字符:</p> <pre class="brush: js; notranslate">"\n\t", "Foo", "\n\t", "Bar", "\n\t", "Baz"</pre> <div class="blockIndicator note"> <p><strong>Note:</strong> 空格是构成 {{DOMxRef("Text")}}节点的一部分,意味着缩进和换行在 <code>Element</code> 节点之间形成单独的 <code>Text</code> 。</p> </div> <h4 id="真实案例">真实案例</h4> <p>下述例子反应了 <code>eachNode</code> 函数是如何在真实场景中使用的:搜索网页中的文本。我们使用一个包装函数 <code>grep</code> 去执行搜索:</p> <pre class="brush: js; notranslate">function grep(parentNode, pattern){ var matches = []; var endScan = false; eachNode(parentNode, function(node){ if(endScan) return false; // Ignore anything which isn't a text node if(node.nodeType !== Node.TEXT_NODE) return; if("string" === typeof pattern){ if(-1 !== node.textContent.indexOf(pattern)) matches.push(node); } else if(pattern.test(node.textContent)){ if(!pattern.global){ endScan = true; matches = node; } else matches.push(node); } }); return matches; }</pre> <p>例如:找到所有包含错别字的 {{DOMxRef("Text")}}:</p> <pre class="brush: js; notranslate">var typos = ["teh", "adn", "btu", "adress", "youre", "msitakes"]; var pattern = new RegExp("\\b(" + typos.join("|") + ")\\b", "gi"); var mistakes = grep(document.body, pattern); console.log(mistakes); </pre> <h2 id="规范">规范</h2> <table class="standard-table"> <thead> <tr> <th scope="col">规范</th> <th scope="col">状态</th> <th scope="col">备注</th> </tr> </thead> <tbody> <tr> <td>{{SpecName("DOM WHATWG", "#interface-node", "Node")}}</td> <td>{{Spec2("DOM WHATWG")}}</td> <td>增加了以下方法: <code>getRootNode()</code></td> </tr> <tr> <td>{{SpecName("DOM4", "#interface-node", "Node")}}</td> <td>{{Spec2("DOM4")}}</td> <td>移除了以下属性: <code>attributes</code>, <code>namespaceURI</code>, <code>prefix</code>, 和 <code>localName</code>.<br> 移除了以下方法: <code>isSupported()</code>, <code>hasAttributes()</code>, <code>getFeature()</code>, <code>setUserData()</code>, and <code>getUserData()</code>.</td> </tr> <tr> <td>{{SpecName("DOM3 Core", "core.html#ID-1950641247", "Node")}}</td> <td>{{Spec2("DOM3 Core")}}</td> <td><code>insertBefore()</code>, <code>replaceChild()</code>, <code>removeChild()</code>, 和 <code>appendChild()</code> 方法在{{DOMxRef("Document")}} 上调用时遇到特定错误时会抛出一个新的异常(<code>NOT_SUPPORTED_ERR</code>)。<br> <code>normalize()</code> 方法已被修改,使得当设定特定的 {{DOMxRef("DOMConfiguration")}} 属性时, {{DOMxRef("Text")}} 节点也能被正确整理。<br> 添加以下方法: <code>compareDocumentPosition()</code>, <code>isSameNode()</code>, <code>lookupPrefix()</code>, <code>isDefaultNamespace()</code>, <code>lookupNamespaceURI()</code>, <code>isEqualNode()</code>, <code>getFeature()</code>, <code>setUserData()</code>, and <code>getUserData().</code><br> 添加以下属性: <code>baseURI</code> 和 <code>textContent</code>.</td> </tr> <tr> <td>{{SpecName("DOM2 Core", "core.html#ID-1950641247", "Node")}}</td> <td>{{Spec2("DOM2 Core")}}</td> <td>修改 <code>ownerDocument</code> 属性,当访问 {{DOMxRef("DocumentFragment")}} 子节点的 <code>ownerDocument</code> 属性也会返回 null。<br> 添加下列属性: <code>namespaceURI</code>, <code>prefix</code>, 和 <code>localName</code>.<br> 添加下列方法: <code>normalize()</code>, <code>isSupported()</code> 和 <code>hasAttributes()</code>.</td> </tr> <tr> <td>{{SpecName("DOM1", "level-one-core.html#ID-1950641247", "Node")}}</td> <td>{{Spec2("DOM1")}}</td> <td>Initial definition.</td> </tr> </tbody> </table> <h2 id="浏览器兼容性">浏览器兼容性</h2> <p>{{Compat("api.Node")}}</p>