四、搜索 DOM
4.1 搜索具有 id 的元素
document.getElementById或者只使用id
javascript1document.getElementById('elem').style.background = 'red' // 通过getElementById搜索对应元素 2// elem 是对带有 id="elem" 的 DOM 元素的引用 3elem.style.background = 'red' // 也可以直接通过id访问 4// id="elem-content" 内有连字符,所以它不能成为一个变量 5// ...但是我们可以通过使用方括号 window['elem-content'] 来访问它
使用 id 方式直接访问 dom 是一种兼容性的支持,并不推荐在项目开发中使用。可以用于在元素来源非常明显且不会跟变量名重复的情况。(可用于写 demo)
如果有具有相同名称的变量,那么则以变量名为优先。
保持 id 的唯一性,全局不要有重复的 id,否则使用搜索 API 搜索某一个元素时,可能会随机返回另一个元素。
document.getElementById 只能被在 document 上调用,没有 elem.getElementById
4.2 querySelectorAll
querySelectorAll(css_selector)方法可以搜索跟 CSS 选择器相匹配的所有元素。
querySelector(css_selector)方法可以搜索跟 CSS 选择器相匹配的第一个元素,相当于 querySelectorAll(css_selector)[0]
html1<ul> 2 <li>The</li> 3 <li>test</li> 4</ul> 5<ul> 6 <li>has</li> 7 <li>passed</li> 8</ul> 9<script> 10 let elements = document.querySelectorAll('ul > li:last-child') 11 12 for (let elem of elements) { 13 alert(elem.innerHTML) // "test", "passed" 14 } 15 let element = document.querySelector('ul > li:last-child') 16 alert(element.innerHTML) // "test" 17</script>
querySelector 方法可以供 elem 调用
html1<div class="container"> 2 <div>123</div> 3</div> 4 5<script> 6 let containerElem = document.querySelector('.container') 7 let div = containerElem.querySelector('div') 8 console.log(div.innerHTML) // 123 9</script>
4.3 getElementsBy*
旧的 API 中还有类似通过标签、类等查找节点的方法。querySelector 功能更强大,写起来更短,所以这些旧 API 通常在老代码中存在
-
elem.getElementsByTagName(tag) 查询标签名的集合
html1<h1>This is a static template</h1> 2<script> 3 const elem = document.getElementsByTagName('h1') 4 console.log(elem[0].innerText) // This is a static template 5</script> -
elem.getElementsByClassName(className) 返回具有给定 css 类的元素
html1<h1 class="template">This is a static template</h1> 2<script> 3 const elem = document.getElementsByClassName('template') 4 console.log(elem[0].innerText) 5</script> -
document.getElementsByName(name) 返回在文档范围内具有给定 name 特性的元素。(很少用)
html1<form action="" name="form"> 2 <input type="text" /> 3</form> 4<script> 5 const elem = document.getElementsByName('form') 6 console.log(elem[0].children) 7</script>
注意点:
- 不要忘记字母 s
- 返回的是一个集合(伪数组)
4.4 实时的集合
所有的“getElementsBy*”返回的都是实时的集合。这样的集合始终反映的是文档的当前状态,并且在文档发生更改时会自动更新。
html1<div>First div</div> 2 3<script> 4 let divByGetElements = document.getElementsByTagName('div') 5 let divBySelector = document.querySelectorAll('div') 6 console.log(divByGetElements.length) // 1 7 console.log(divBySelector.length) // 1 8</script> 9 10<div>Second div</div> 11 12<script> 13 console.log(divByGetElements.length) // 2 14 console.log(divBySelector.length) // 1 15</script>
上面的例子中,通过两种方式搜索出来的 div,在文档发生改变后,通过getElementsBy*获取的元素集合更新了,而通过querySelector获取的元素集合是静态的,不会实时更新。
4.5 matches
matches 可以检查elem是否和 css 选择器相匹配。它返回布尔值。
当我们遍历元素时,可以用这个 API 过滤我们需要的元素
javascript1<a href="http://example.com/file.zip">...</a> 2<a href="http://ya.ru">...</a> 3 4<script> 5 // 不一定是 document.body.children,还可以是任何集合 6 for (let elem of document.body.children) { 7 if (elem.matches('a[href$="zip"]')) { 8 alert("The archive reference: " + elem.href ); 9 } 10 } 11</script>
4.6 closest
elem.closest(css_selector)这个 API 可以返回最靠近的并且与 css 选择器相匹配的祖先。elem 自己也会被搜索。
换句话说,方法closest在元素中得到了提升,并检查每个父级和自己。如果与 css 选择器相匹配,则会返回对应的祖先元素(包括自己)
html1<h1>这是外层元素</h1> 2<div> 3 <ul> 4 <li>li1</li> 5 <li>li2</li> 6 <li>li3</li> 7 </ul> 8</div> 9<script> 10 let elem = document.body.querySelector('li') 11 console.log(elem.closest('li').innerHTML) // li1 12 console.log(elem.closest('ul').tagName) // UL 13 console.log(elem.closest('div').tagName) // DIV 14 console.log(elem.closest('h1').tagName) // 找不到 15</script>
4.7 contains
elemA.contains(elemB)这个 API 可以用来检查元素 A 是否是另一个元素 B 的祖先(元素 B 是否在元素 A 内),它返回 boolean 值。
如果 elemA===elemB,那么会返回 true
html1<h1>这是外层元素</h1> 2<div> 3 <ul> 4 <li>li1</li> 5 <li>li2</li> 6 <li>li3</li> 7 </ul> 8</div> 9<script> 10 let divElem = document.body.querySelector('div') 11 let h1Elem = document.body.querySelector('h1') 12 let ulElem = divElem.querySelector('ul') 13 let liElem = ulElem.querySelector('li') 14 console.log(divElem.contains(ulElem)) // true 15 console.log(divElem.contains(liElem)) // true 16 console.log(ulElem.contains(liElem)) // true 17 console.log(divElem.contains(h1Elem)) // false 18</script>
4.8 小结
在 DOM 中搜索节点,可以用以下方式:
| 方法名 | 搜索方式 | 能够给元素调用 | 实时性 |
|---|---|---|---|
| querySelector | CSS-selector | ✅ | ❌ |
| querySelectorAll | CSS-selector | ✅ | ❌ |
| getElementById | id | ❌ | ❌ |
| getElementsByTagName | tag 或者 * | ✅ | ✅ |
| getElementsByClassName | class | ✅ | ✅ |
| getElementsByName | Name | ❌ | ✅ |
最常用的是 querySelector 和 querySelectorAll
此外:
elem.matches(css_selector)这个 API 用于检查 elem 与 css 选择器是否匹配
elem.closest(css_selector)这个 API 用于检查 elem 与 css 选择器相匹配的祖先(包括自己)
elemA.contains(elemB)这个 API 用于检查子级与父级的关系 —— 如果 elemA 包含 elemB(或者相等),则返回 true