查找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 單個元素
相關文章