# querying elements

[JS](../../js) ⟩ [browser](..) ⟩ [DOM]() ⟩ selecting elements

{% tabs %}
{% tab title="📘 手冊" %}
* [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList)
* Element ⟩
  * [.closest()](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest) - 往上選。
  * [.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector) - 往下選。
  * [.querySelectorAll()](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll) - returns [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList).
  * [.matches()](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) - 只跟自己比較，不往上選，也不往下選。
* Document ⟩
  * [.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
  * [.querySelectorAll()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)
* DocumentFragment ⟩
  * [.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/querySelector)
  * [.querySelectorAll()](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/querySelectorAll)
{% endtab %}

{% tab title="🔴 主題" %}
* [use](../../component/use "mention") - do not query web components too early.
* [dom](querying-elements/dom "mention")
* [elem.isinside](type/element/+ext/elem.isinside "mention")
* [elem.isheading](type/element/+ext/elem.isheading "mention")
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="warning" %}
The <mark style="color:yellow;">**return value**</mark> of [querySelectorAll()](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector) is <mark style="color:red;">**not**</mark> an **array** of [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) objects. Instead, it is an <mark style="color:yellow;">**iterable**</mark> <mark style="color:orange;">**array-like**</mark> object known as a [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList).&#x20;
{% endhint %}

{% hint style="warning" %}
* [`querySelector()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector) , [`querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll) return a _<mark style="color:orange;">**static**</mark>_ [nodelist](type/nodelist "mention").
* [`Node.childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) is a _<mark style="color:red;">**live**</mark>_ [nodelist](type/nodelist "mention").
{% endhint %}

{% hint style="info" %}
NodeList objects&#x20;

* have a <mark style="color:yellow;">**length**</mark> property, can be <mark style="color:yellow;">**indexed**</mark> like arrays.&#x20;
* can <mark style="color:yellow;">**loop**</mark> with traditional <mark style="color:blue;">**for( ; ; )**</mark> loop, <mark style="color:blue;">**for-of**</mark> loop, <mark style="color:blue;">**forEach()**</mark> method.&#x20;
* can convert into <mark style="color:yellow;">**array**</mark> with <mark style="color:blue;">**Array.from()**</mark>.
{% endhint %}

{% hint style="danger" %}
Some older browsers have <mark style="color:red;">**not implemented**</mark> <mark style="color:blue;">`NodeList.forEach()`</mark> <mark style="color:red;">**nor**</mark> <mark style="color:blue;">`Array.from()`</mark>. This can be circumvented by using [`Array.prototype.forEach()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)  👉 💈範例
{% endhint %}

{% hint style="danger" %}
* <mark style="color:red;">`::first-line`</mark> and <mark style="color:red;">`::first-letter`</mark> <mark style="color:orange;">**pseudo-elements**</mark> match <mark style="color:yellow;">**portions**</mark> of <mark style="color:yellow;">**text nodes**</mark> rather than actual elements, they <mark style="color:red;">**will not match**</mark> if used with <mark style="color:blue;">querySelectorAll()</mark> or <mark style="color:blue;">querySelector()</mark>.
* many browsers <mark style="color:red;">**will refuse**</mark> to return matches for the <mark style="color:red;">`:link`</mark> and <mark style="color:red;">`:visited`</mark> <mark style="color:orange;">**pseudo-classes**</mark>.
{% endhint %}
{% endtab %}

{% tab title="💈範例" %}
```javascript
// ⭐️ traditional for-loop
for (let i = 0; i < nodeList.length; i++) {
  let node = nodeList[i];
}

// ⭐️ for-of loop
const list = document.querySelectorAll('input[type=checkbox]');

for (let checkbox of list) {
  checkbox.checked = true;
}

// ⭐️ for browsers which don't support NodeList.forEach()
Array.prototype.forEach.call(list, (checkbox) => {
  checkbox.checked = true;
});
```
{% endtab %}

{% tab title="📗 參考" %}
* [ ] JavaScript The Definitive Guide (15.3 Scripting Document)
{% endtab %}

{% tab title="👥 相關" %}
* [element](type/element "mention")
* [selectors](../../css/selectors "mention")
* [pseudo-class](../../css/selectors/pseudo-class "mention")
* [pseudo-element](../../css/selectors/pseudo-element "mention")
* [nodelist-vs.-array](type/nodelist/nodelist-vs.-array "mention")
{% endtab %}
{% endtabs %}
