查找DOM元素的二三事:getElement* 和 querySelector*

直接使用id

若是元素有 id 属性,那么该 id 也会有一个同名全局变量; 若是声明了同名变量,则会被声明的变量覆盖css

<div id="test">Test Element</div>
  <div id="test-inner">Test Inner Element</div>

  <div id="other">Test Element</div>

  <script>
    console.log(test)
    console.log(window.test)

    console.log(window['test-inner'])

    let other = '掘金'
    console.log(other)
  </script>
复制代码

运行结果

规范 中描述了这种行为,浏览器尝试了混合 JS 和 DOM 的命名空间。但这仅对简单脚本有效,由于它们可能会产生命名冲突;并且当咱们在 JS 中查看时,由于没法在视图中查看 HTML,因此变量的来源可能会很模糊;故此,建议不用这种方式获取元素。web

document.getElementById('id')

强调三点:数组

  • getElementById 只能在 document 对象上调用,它会在整个文档中查找给定的 id;浏览器

  • getElementById 返回单个元素;bash

  • 若是有多个元素具备同名 id,那么 getElementById 的行为将不可预测;浏览器将随机返回其余的一个;请严格遵照 id 的惟一性规则;app

getElementsBy*

具体方法有:dom

elem.getElementsByTagName(tag)

  • 适用于 任何节点
  • tag 能够是具体的标签名,也能够是指代任何标签的 '*' ;
  • 返回值是一个的live集合 (不是数组);

elem.getElementsByClassName(className)

  • 适用于 任何节点
  • 返回值是一个的live集合 (不是数组);

document.getElementsByName(name)

  • 只适用于 document 对象;
  • name 指的元素的 name 属性;
  • 返回值是一个的live集合 (不是数组);

getElementsByName 示例:ui

<ul id="ul">
    <li name="li">1</li>
    <li>2</li>
    <li>3</li>
  </ul>

  <script>
    let ul = document.getElementById('ul')

    let documentLi = document.getElementsByName('li')
    console.log('documentLi:', documentLi)

    let elemLi = ul.getElementsByName('li')
    console.log('elemLi:', elemLi)
  </script>
复制代码

运行结果

querySelector*

具体方法有:spa

elem.querySelectorAll(css)

  • 适用于 任何节点
  • css 指合法的 css选择器;
  • 返回值是一个的static集合 (不是数组);

elem.querySelector(css)

  • 适用于 任何节点;
  • css 指合法的 css选择器;
  • 返回值是给定 CSS 选择器的第一个元素,等同于 elem.querySelectorAll(css)[0]

其它方法

elem.matches(css)

matches 不会查找任何内容,它检查 elem 是否匹配给定的 CSS 选择器,返回 true 或者 false。code

elem.closest(css)

closest 会查找与 CSS 选择器匹配的最接近的祖先(elem 本身也会被搜索),返回单个元素

elemA.contains(elemB)

contains 用于检查父子关系,elemB 在 elemA中 或者当 elemA === elemB,返回 true

集合

到这,再来讲说 live集合static集合

live集合:反映文档的当前状态,它是实时的、动态的,即在文档变化时,集合的内容能够自动更新; getElementsBy* 均返回live集合。

static集合:则相反,它是不变的、固定的,即在文档变化时,集合的内容不会变化;querySelectorAll 返回static集合。

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  
  <script>
    //  分别调用 getBy 、 queryAll (只有获取li的方法不一样)
    
    getBy()     // 分别输出 3 和 4
    queryAll()     // 分别输出 3 和 3

    function getBy() {
      const  ul = document.getElementById('ul')
      
      //    获取li
      const lis = document.getElementsByTagName('li')
      console.log(lis.length)
      
      //    向ul中追加一个li
      const newLi  = document.createElement('li')
      newLi.textContent = 'new li'
      ul.appendChild(newLi)
      
      console.log(lis.length)
    }

    function queryAll() {
      const  ul = document.getElementById('ul')
      
      //    获取li
      const lis = document.querySelectorAll('li')
      console.log(lis.length)
      
      //    向ul中追加一个li
      const newLi  = document.createElement('li')
      newLi.textContent = 'new li'
      ul.appendChild(newLi)
      
      console.log(lis.length)
    }
  </script>
复制代码

很容易看到不一样之处:在文档中出现一个新的 li 后,live集合的元素会增长一个,static集合则不会增长。

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  
  <script>
    getBy()     

    function getBy() {
      const  ul = document.getElementById('ul')
      const lis = document.getElementsByTagName('li')
      
      for (let i = 0; i < lis.length; i++) {
        const newLi  = document.createElement('li')
        newLi.textContent = i
        ul.appendChild(newLi)
      }
    }
  </script>
复制代码

很明显 这个for循环,会是一个无限循环,由于当 i增长的时候, lis.length 也会增长。

总结

6 种主要的方法,能够在 DOM 中进行搜素

方法 匹配方式 适用对象 返回值
getElementById id document 单个元素
getElementsByName name document live集合
getElementsByTagName tag or '*' anyNode live集合
getElementsByClassName className anyNode live集合
querySelectorAll CSS-selector anyNode static集合
querySelector CSS-selector anyNode 单个元素
相关文章