使用 Vanilla JS 操作文档对象模型时,您将直接访问 Document 和 Nodes。一个文档包含Elements,特别是HTMLElements 和SVGElements,它们都是Nodes。 Element 也可能包含 Text。
寻找元素
您可以获得第一个与mynode.querySelector() 匹配的CSS 选择器的元素,以及与myNode.querySelectorAll() 匹配选择器的所有 元素。大多数情况下myNode 将是Document,因此您可以在文档中获得与选择器匹配的任何内容 - 但是,当myNode 是一个节点时,您只能查看节点的后代元素。
document.querySelectorAll('p:hover'); // Returns a NodeList of hovered paragraphs
这类似于jQuery('p:hover')。
还有更专业的方法,例如:
具有不言自明的名称。请注意,.getElementBy... 返回单个元素,而.getElementsBy...(复数元素s)返回NodeList,它本质上是一个节点数组,但它没有标准的数组方法。
另请参阅:What's the best way to loop through a set of elements in JavaScript?
每个元素也可能有一个:
还有NodeLists 的:
这样,我们就可以遍历DOM了。
例如,在此处获取#clickme 的父级中第一个段落元素的最后一个子级:
document.getElementById('clickme').addEventListener('click', function() {
console.log(this.parentNode.getElementsByTagName('p')[0].lastChild);
});
<div>
<blockquote>This is a really great quote.</blockquote>
<p>This is a <em>really</em> interesting paragraph. <span>this will be selected</span></p>
<p>In fact, here's another!</p>
<button id="clickme">Click me!</button>
</div>
...您找到它的parentNode,在其上使用getElementsByTagName 以仅获取段落后代,取其中的第一个,并获取其lastChild。
要获取其中包含的文本,您可以获取其文本节点(其第一个子节点),然后使用text.wholeText。
创建和删除
您可以使用document.createElement('aTagName') 创建一个元素,或者使用newElement = myElement.cloneNode() 克隆另一个元素。传递 cloneNode true 作为它的第一个参数来复制它的后代。不要克隆具有 ID 的元素,因为这会导致 2 个具有相同 ID 的元素出现在同一个文档中。
然后您可以使用parent.appendChild(newElement) 将新元素(或现有元素)附加到父元素,或使用parent.insertBefore(newElement, referenceElement) 将其附加到另一个元素之后。 insertAfter 方法不存在,但可以创建:
HTMLElement.prototype.insertAfter = function(newEl, refEl) {
if (refEl.nextSibling) refEl.parentNode.insertBefore(newEl, refEl.nextSibling);
else refEl.parentNode.appendChild(newEl);
};
可以使用parent.removeChild() 删除节点,或者使用parent.replaceChild(newChild) 替换节点,或者直接使用mynode.remove() 删除节点。
function poof() {
this.remove();
}
var elements = document.getElementsByClassName('poof');
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', poof);
}
<span class="poof">hi,</span>
<span class="poof">click</span>
<span class="poof">to</span>
<span class="poof">delete</span>
<span class="poof">me;</span>
<span class="poof">it</span>
<span class="poof">was</span>
<span class="poof">fun</span>
<span class="poof">being</span>
<span class="poof">a</span>
<span class="poof">span</span>
类和样式
“和样式”是指类。 样式用于 CSS。您只能将 CSS 样式应用于已使用 JavaScript 添加了类的元素。1
HTML 中的元素有一个classList 属性,它是一个DOMTokenList,代表一个以空格分隔的属性,在本例中为class。你可以在classList中.add()、.remove()和.toggle()类或者检查.contains()是不是一个类。
document.getElementById('clickme').addEventListener('click', function() {
document.getElementById('colors').classList.toggle('green');
});
.green { color: green }
<div id="colors">hello!</div>
<button id="clickme">Click me!</button>
属性
可以使用querySelector 和querySelectorAll 选择具有某些属性的元素。大多数属性是您正在使用的元素的属性。例如:
myDiv.hidden = true; // Hides element from view and from screenreaders
但如果不是,则可以使用getAttributeNode、setAttributeNode 和removeAttributeNode 访问任何属性。 AttributeNodes 有 ownerElements 和 values。
“data-*”属性可以通过myelement.dataset 访问。例如,mydiv.dataset.pie = 'yummy' 会将data-pie="yummy" 添加到 div。
活动
事件稍微复杂一些。 绑定一个(比如jQuery('selector').on)非常简单:
myElement.addEventListener('event-name', afunction);
(其他对象也有这个方法——例如,window)
事件也可以删除:
myelement.removeEventListener('event-name', afunction);
见:removeEventListener
活动列表可以在here找到。
传递给addEventListener 的函数将被传递事件发生的一个参数,并具有事件侦听器绑定到的元素的this。
然而,事件并非如此简单:像单击按钮这样微不足道的事情可能会针对不同的元素和不同的事件触发许多事件侦听器。
– Browser Input Events: Can We Do Better Than The Click? Smashing Magazine
另见:What is event bubbling and capturing?
1如果确实需要用JS修改样式,可以使用myElement.style.styleProperty = 'value'来更改内联样式属性。