Node
>文档对象模型的 Node 接口是许多其他 DOM API 对象所基于的抽象基类,因此这些对象类型可以以类似的方式使用,并且常常可以互换。作为抽象类,不存在纯粹的 Node 对象。所有实现 Node 功能的对象都基于它的某个子类。最主要的是 Document、Element 和 DocumentFragment。
此外,每一种 DOM 节点都由基于 Node 的接口表示。其中包括 Attr、CharacterData(Text、Comment、CDATASection 和 ProcessingInstruction 都基于它)以及 DocumentType。
在某些情况下,基类 Node 接口的某一特性可能不适用于某个子接口;此时,继承的节点可能返回 null 或抛出异常,具体取决于情形。例如,尝试向不能拥有子节点的节点类型添加子节点会抛出异常。
实例属性
除了下列属性外,Node 还从其父接口 EventTarget 继承属性。
Node.baseURI只读-
返回表示包含该
Node的文档的基础 URL 的字符串。 Node.childNodes只读-
返回包含此节点所有子节点(包括元素、文本和注释)的实时
NodeList。NodeList是实时的,意味着如果Node的子节点发生变化,NodeList对象会自动更新。 Node.firstChild只读-
返回表示该节点第一个直接子节点的
Node,若没有子节点则为null。 Node.isConnected只读-
布尔值,表示该 Node 是否(直接或间接)连接到上下文对象,例如常规 DOM 中的
Document对象,或影子 DOM 中的ShadowRoot。 Node.lastChild只读-
返回表示该节点最后一个直接子节点的
Node,若没有子节点则为null。 Node.nextSibling只读-
返回表示树中下一个节点的
Node,若不存在则为null。 Node.nodeName只读-
返回包含该
Node名称的字符串。名称结构因节点类型而异。例如,HTMLElement会包含对应标签的名称,如HTMLAudioElement为'AUDIO';Text节点为'#text';Document节点为'#document'。 Node.nodeType只读-
返回表示节点类型的
unsigned short。可能的值有:名称 值 ELEMENT_NODE1ATTRIBUTE_NODE2TEXT_NODE3CDATA_SECTION_NODE4PROCESSING_INSTRUCTION_NODE7COMMENT_NODE8DOCUMENT_NODE9DOCUMENT_TYPE_NODE10DOCUMENT_FRAGMENT_NODE11 Node.nodeValue-
获取或设置当前节点的值。
Node.ownerDocument只读-
返回此节点所属的
Document。如果节点本身就是文档,则返回null。 Node.parentNode只读-
返回此节点的父
Node。如果不存在这样的节点——例如,此节点位于树的顶端,或不属于任何树——则此属性返回null。 Node.parentElement只读Node.previousSibling只读-
返回表示树中上一个节点的
Node,若不存在则为null。 Node.textContent-
获取或设置元素及其所有后代的文本内容。
实例方法
除了下列方法外,Node 还从其父接口 EventTarget 继承方法。
Node.appendChild()-
将指定的
childNode参数添加为当前节点的最后一个子节点。如果该参数引用了 DOM 树中已存在的节点,该节点会从其当前位置分离,并附加到新位置。 Node.cloneNode()-
克隆一个
Node,并可选择是否克隆其全部内容。默认会克隆该节点的内容。 Node.compareDocumentPosition()-
将当前节点的位置与任意其他文档中的另一个节点进行比较。
Node.contains()-
返回
true或false,表示某个节点是否为调用节点的后代。 Node.getRootNode()-
返回上下文对象的根,可选地在可用时包含影子根。
Node.hasChildNodes()-
返回布尔值,表示该元素是否有任何子节点。
Node.insertBefore()-
在指定父节点下,将一个
Node插入为参考节点之前的子节点。 Node.isDefaultNamespace()-
接受命名空间 URI 作为参数,若该命名空间是给定节点上的默认命名空间则返回
true,否则返回false。 Node.isEqualNode()-
返回布尔值,表示两个节点是否类型相同且所有定义性数据点都匹配。
Node.isSameNode()-
返回布尔值,表示两个节点是否为同一个节点(即引用同一对象)。
Node.lookupPrefix()-
返回包含给定命名空间 URI 的前缀的字符串(若存在),否则返回
null。当可能有多个前缀时,结果取决于实现。 Node.lookupNamespaceURI()-
接受前缀并返回给定节点上与之关联的命名空间 URI(若找到),否则返回
null。为前缀传入null将返回默认命名空间。 Node.normalize()-
清理此元素下的所有文本节点(合并相邻节点,移除空节点)。
Node.removeChild()-
从当前元素移除一个子节点,该节点必须是当前节点的子节点。
Node.replaceChild()-
用参数中给出的第二个节点替换当前节点的一个子
Node。
事件
selectstart-
当用户在此节点中开始新的选区时触发。
示例
>移除节点内嵌套的所有子节点
此函数会反复移除元素的第一个子节点,直到没有子节点为止。
function removeAllChildren(element) {
while (element.firstChild) {
element.removeChild(element.firstChild);
}
}
使用此函数只需一次调用。下面我们清空文档的 body:
removeAllChildren(document.body);
另一种做法是将 textContent 设为空字符串:document.body.textContent = ""。
递归遍历子节点
以下函数会为根节点所包含的每个节点(包括根节点自身)递归调用回调函数:
function eachNode(rootNode, callback) {
if (!callback) {
const nodes = [];
eachNode(rootNode, (node) => {
nodes.push(node);
});
return nodes;
}
if (callback(rootNode) === false) {
return false;
}
if (rootNode.hasChildNodes()) {
for (const node of rootNode.childNodes) {
if (eachNode(node, callback) === false) {
return;
}
}
}
}
该函数会为 rootNode 的每个后代节点(包括根节点自身)递归调用一个函数。
如果省略 callback,函数会改为返回一个 Array,其中包含 rootNode 及其内部的所有节点。
如果提供了 callback,并且调用时返回 false,则中止当前递归层级,函数在上一层父节点处恢复执行。这可用于在找到某个节点后中止循环(例如搜索包含特定字符串的文本节点)。
该函数有两个参数:
rootNode-
将递归遍历其后代的
Node对象。 callback可选-
可选的回调函数,只接收一个
Node参数。如果省略,eachNode会返回rootNode内每个节点(包括根节点自身)组成的Array。
下面展示 eachNode() 函数的实际用法:在网页上搜索文本。
我们使用名为 grep 的包装函数来执行搜索:
function grep(parentNode, pattern) {
let matches = [];
let endScan = false;
eachNode(parentNode, (node) => {
if (endScan) {
return false;
}
// 忽略非文本节点
if (node.nodeType !== Node.TEXT_NODE) {
return;
}
if (typeof pattern === "string" && node.textContent.includes(pattern)) {
matches.push(node);
} else if (pattern.test(node.textContent)) {
if (!pattern.global) {
endScan = true;
matches = node;
} else {
matches.push(node);
}
}
});
return matches;
}
规范
| 规范 |
|---|
| DOM> # interface-node> |