如何在没有像jQuery这样的库的情况下操作DOM?

时间:2015-04-13 00:44:46

标签: javascript dom

我习惯使用jQuery来操作DOM,例如:

var mything = $("#mything");
mything.on("click", function() {
    mything.addClass("red");
    mything.html("I have sinned.");
});

但现在我想用Vanilla JavaScript做同样的事情。这可能吗?我该怎么办?

  

注意:此问题旨在成为有关Vanilla JavaScript DOM操作的综合资源。

1 个答案:

答案 0 :(得分:22)

使用Vanilla JS操作文档对象模型时,您将直接访问DocumentNode。一个文档包含Element个,特别是HTMLElementSVGElement,它们都是Node个。 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,这实际上是一个节点数组,但它并没有; t有标准的数组方法。

另请参阅:What's the best way to loop through a set of elements in JavaScript?

每个元素也可能有:

NodeList的:

通过这种方式,我们可以遍历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;
&#13;
&#13;

...您找到了parentNode,在其上使用getElementsByTagName仅获取段落后代,取其中的第一个,并获取其lastChild

要获取其中包含的文本,您可以获取其文本节点(其第一个子节点),然后使用text.wholeText

创造&amp;删除

您可以使用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()内联移除节点。

&#13;
&#13;
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;
&#13;
&#13;

类和样式

&#34;和样式,&#34;我只是说课。 样式适用于CSS。您只能将CSS样式应用于已添加JavaScript类的元素。 1

HTML中的元素具有classList属性,该属性是DOMTokenList,表示空格分隔的属性,在本例中为class。您可以在classList中使用.add().remove().toggle()类,也可以检查它是.contains()类。

&#13;
&#13;
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;
&#13;
&#13;

属性

可以使用querySelectorquerySelectorAll选择具有特定属性的元素。大多数属性都是您已经使用过的元素的属性。例如:

myDiv.hidden = true; // Hides element from view and from screenreaders

但如果他们不是,则可以使用getAttributeNodesetAttributeNoderemoveAttributeNode访问任何属性。 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);

请参阅:removeEventListener

可以找到事件列表here

传递给addEventListener的函数将传递事件发生的参数,并且事件监听器绑定的元素的this

然而,事件并非如此简单:像点击按钮一样微不足道的事情可能会激活不同元素和不同事件的许多事件监听器。

Click event path on iOS

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>