我习惯使用jQuery来操作DOM,例如:
var mything = $("#mything");
mything.on("click", function() {
mything.addClass("red");
mything.html("I have sinned.");
});
但现在我想用Vanilla JavaScript做同样的事情。这可能吗?我该怎么办?
注意:此问题旨在成为有关Vanilla JavaScript DOM操作的综合资源。
答案 0 :(得分:22)
使用Vanilla JS操作文档对象模型时,您将直接访问Document
和Node
。一个文档包含Element
个,特别是HTMLElement
和SVGElement
,它们都是Node
个。 Element
也可能包含Text
。
您可以使用mynode.querySelector()
获取与CSS选择器匹配的第一个元素,以及将选择器与myNode.querySelectorAll()
匹配的所有元素。大部分时间myNode
都是Document
,因此您可以在文档中获取与选择器匹配的任何内容 - 但是,您只能查看节点的后代 myNode
是一个元素。
document.querySelectorAll('p:hover'); // Returns a NodeList of hovered paragraphs
这类似于jQuery('p:hover')
。
还有更专业的方法,如:
myNode.getElementById()
myNode.getElementsByTagName()
myNode.getElementsByClassName()
myNode.getElementsByName()
其中有不言自明的名字。请注意,.getElementBy...
会返回单个元素,而.getElementsBy...
(多元素 s )会返回NodeList
,这实际上是一个节点数组,但它并没有; t有标准的数组方法。
另请参阅:What's the best way to loop through a set of elements in JavaScript?
每个元素也可能有:
parentNode
previousSibling
previousElementSibling
(不包括文字节点)nextSibling
nextElementSibling
(不包括文字节点)firstChild
firstElementChild
(不包括文字节点)lastChild
lastElementChild
(不包括文字节点)childElementCount
(与children.length
相同)和NodeList
的:
childNodes
children
(不包括文字节点)通过这种方式,我们可以遍历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>
&#13;
...您找到了parentNode
,在其上使用getElementsByTagName
仅获取段落后代,取其中的第一个,并获取其lastChild
。
要获取其中包含的文本,您可以获取其文本节点(其第一个子节点),然后使用text.wholeText
。
您可以使用document.createElement('aTagName')
创建元素,也可以使用newElement = myElement.cloneNode()
克隆另一个元素。通过cloneNode
true
,因为它的第一个参数也会复制其后代。不要使用ID克隆元素,因为它会导致具有相同ID的2个元素出现在同一文档中。
然后,您可以使用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);
}
&#13;
<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>
&#13;
&#34;和样式,&#34;我只是说课。 样式适用于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');
});
&#13;
.green { color: green }
&#13;
<div id="colors">hello!</div>
<button id="clickme">Click me!</button>
&#13;
可以使用querySelector
和querySelectorAll
选择具有特定属性的元素。大多数属性都是您已经使用过的元素的属性。例如:
myDiv.hidden = true; // Hides element from view and from screenreaders
但如果他们不是,则可以使用getAttributeNode
,setAttributeNode
和removeAttributeNode
访问任何属性。 AttributeNodes具有 ownerElements 和 value s。
&#34;数据 - *&#34;可以使用myelement.dataset
访问属性。例如,mydiv.dataset.pie = 'yummy'
会将data-pie="yummy"
添加到div。
事件稍微复杂一些。 绑定一个(如jQuery('selector').on
)非常简单:
myElement.addEventListener('event-name', afunction);
(其他对象也有此方法 - 例如,window
)
事件也可以删除:
myelement.removeEventListener('event-name', afunction);
可以找到事件列表here。
传递给addEventListener
的函数将传递事件发生的参数,并且事件监听器绑定的元素的this
。
然而,事件并非如此简单:像点击按钮一样微不足道的事情可能会激活不同元素和不同事件的许多事件监听器。
Smashing Magazine
- Browser Input Events: Can We Do Better Than The Click?
另请参阅:What is event bubbling and capturing?
1 如果您确实需要使用JS修改样式,请使用myElement.style.styleProperty = 'value'
更改内联样式属性。 < / p>