英文 | https://levelup.gitconnected.com/useful-dom-traversal-methods-d2b55cf8e25c
翻译 | web前端开发(ID:web_qdkf)
客户端JavaScript的主要用途是动态地处理网页。我们可以使用DOM节点对象可用的DOM遍历方法和属性来做到这一点。
对于任何给定的节点,添加或更改子元素和同级元素都很容易,因为DOM节点对象中内置了执行这些操作的属性。以下是DOM Node对象用于获取父节点,子节点和同级节点或元素的方法。
appendChild
这些appendChild方法使我们可以将子节点附加到给定的HTML元素上,作为当前节点的最后一个子节点。如果参数引用了DOM树上的现有节点,则该节点将从其当前位置脱离并附加到其新位置。
它使用一个参数,这是一个DOM Node对象。
例如,在以下HTML中给定2个现有节点:
<div id ='foo'>
foo
</ div>
<div id ='bar'>
bar
</ div>
我们可以将ID为bar的元素作为子元素附加到ID为bar的元素,如下所示:
const foo = document.querySelector('#foo');
const bar = document.querySelector('#bar');
foo.appendChild(bar);
一旦运行它,我们将获得以下结构:
<div id =“ foo”>
foo
<div id =“ bar”>
bar
</ div>
</ div>
我们还可以使用它来创建动态创建的元素。例如,如果我们具有以下HTML:
<div id ='foo'>
foo
</ div>
然后,我们可以编写以下代码,将一个新p元素附加到ID为foo的div上:
const foo = document.querySelector('#foo'); const bar = document.createElement('p'); bar.textContent ='bar';foo.appendChild(bar);
在上面的代码中,我们用来createElement创建一个新p元素。然后,我们设置textContent属性以在p元素内添加文本。最后,我们可以appendChild在foo与bar作为参数,以连接bar为一体的儿童foo。
cloneNode
该cloneNode方法将克隆Node对象,并克隆其所有内容。默认情况下,它不会克隆Node的所有内容。
它带有一个参数,这是一个可选参数,指示它是否为深度克隆,这意味着将克隆所有内容。true意味着做一个深克隆,false否则。
例如,给定以下HTML:
<div>
foo
</ div>
我们可以编写以下JavaScript代码来克隆div,然后将其body作为最后一个子元素附加到元素:
const fooDiv = document.querySelector('div');
const fooClone = fooDiv.cloneNode(true);
document.body.appendChild(fooClone);
我们传递true给该cloneNode方法以克隆所有内容。然后我们调用appendChild上document.body与作为参数,将其添加为孩子通过克隆的对象body。
compareDocumentPosition
该compareDocumentPosition方法将给定节点的位置与任何文档中的另一个节点进行比较。它以DOM Node对象为参数。
它返回具有以下可能值的位掩码
- DOCUMENT_POSITION_DISCONNECTED — 1
- DOCUMENT_POSITION_PRECEDING — 2
- DOCUMENT_POSITION_FOLLOWING — 4
- DOCUMENT_POSITION_CONTAINS — 8
- DOCUMENT_POSITION_CONTAINED_BY — 16
- DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC — 32
例如,给定以下HTML:
<div id ='foo'>
foo
</ div>
<div id ='bar'>
bar
</ div>
我们可以编写以下JavaScript来比较ID为foo的div和ID为bar的div的位置:
const foo = document.querySelector('#foo');
const bar = document.querySelector('#bar');
const relativePos = foo.compareDocumentPosition(bar);
console.log(relativePos);
上面的代码应该为4 relativePos,这意味着ID为bar的元素紧随ID为foo的元素。
包含
该contains方法检查DOM节点是否在给定节点内。它带有一个参数,这是一个Node对象,我们要检查它是否在调用此方法的对象内。
它返回true参数中的节点是否在被调用的节点之内,false否则返回。
例如,给定以下HTML:
<div id ='foo'>
foo
</ div>
<div id ='bar'>
bar
</ div>
然后,我们可以编写以下JavaScript来检查ID为bar的div是否在ID为foo的div内:
const foo = document.querySelector('#foo');
const bar = document.querySelector('#bar');
const fooContainsBar = foo.contains(bar);
console.log(fooContainsBar);
当然,fooContainsBar应该是false,因为ID为foo的div不在ID为bar的div内。
另一方面,如果我们使用以下HTML代替:
<div id ='foo'> foo <div id ='bar'> bar </ div></ div>
然后使用与第一个示例相同的JavaScript代码,因为ID为foo的div fooContainsBar应该为true位于ID为bar的div内。
getRootNode
该getRootNode方法返回Node对象的根,如果有的话,可以选择包括影子根。
它使用带有以下属性的对象的可选参数:
- composed—一个布尔值,指示应该包括影子根。默认为false
它返回Node,该Node返回一个元素,该元素是给定Node的根,否则将为shadow DOM中的元素返回shadow root。
例如,如果我们具有以下HTML:
<div id ='foo'>
foo
</ div>
然后我们可以getRootNode如下调用该方法:
const foo = document.querySelector('#foo');
const root = foo.getRootNode();
console.log(root);
我们应该将HTML文档作为根节点,因为它不在影子DOM中。
该根将是Web组件的影子根。例如,如果我们具有以下Web组件:
customElements.define('custom-p',
class extends HTMLElement {
constructor() {
super();
const pElem = document.createElement('p');
pElem.id = 'p-element';
pElem.textContent = 'shadow p'
const shadowRoot = this.attachShadow({
mode: 'open'
});
shadowRoot.appendChild(pElem);
}
}
);
并且我们在HTML代码中添加了Web组件:
<custom-p> </ custom-p>
然后,我们可以p-element通过编写以下内容获取具有ID的元素的根节点:
const pElement = document.querySelector('custom-p')。shadowRoot.querySelector('#p-element');
const rootNode = pElement.getRootNode();
console.log(rootNode);
首先,我们获得custom元素,然后获得该shadowRoot属性,该属性使我们能够访问custom-pWeb组件的影子DOM 。然后我们可以获得pID p-element为影子根的元素。
在那之后,我们通过调用得到它的根节点getRootNode上pElement表示p与ID元素p-element。
本console.log应该得到我们的Web组件的影子根。
结论
使用这些DOM遍历方法,我们可以设置节点,但我们希望将其用于简单情况。另外,还有一些方法可以检查一个元素是否是另一个元素的子元素,并可以获取给定元素的根节点。