原生 JavaScript 如何實現通過自定義屬性定位/篩選節點

weixin_34006468發表於2016-08-16

這是一個小問題,但是我查資料的過程比想象的漫長,所以把問題寫出來,希望可以幫到需要的人。尋找解決辦法的可以直接看解決辦法,最後的解決過程是一些額外的東西。

問題描述

在 jQuery 中有這樣的用法:var $ele = $("*[data_name=aa]");
目的是匹配所有節點(* 的作用)中 data 屬性為 aa 的節點([data=aa]的作用)。
例如這樣的標籤:<div data_name="aa"></div>

那麼如果要用原生的 JavaScript 實現該怎麼辦呢?

解決辦法

下面是我目前在 StackOverflow 上看到的解決辦法,可能不完全,歡迎補充。

1. querySelectorAll

var ele = document.querySelectorAll('[data_name="aa"]')
此時返回的是一個 NodeList 物件(我覺得它類似陣列,在 console 裡輸出時是這樣) ,也就是說當頁面中存在多個 data_name 的屬性值為 aa 時,都能匹配返回。

參考 Wojtek Kruszewski答案
MDN文件

2. 自己寫方法

    function selector(attribute, value) {
            var all = document.getElementsByTagName('*');
            for (var i = 0; i < all.length; i++) {
                if (all[i].getAttribute(attribute) == value) {
                    return all[i];
                }
            } }

參考 tazo todua答案

這個方法的返回值是一個 data_name 的屬性值為 aa的節點。在 Chrome 中執行 alert 此返回值時,得到的是[object HTMLDivElement]。
但注意這種方法有個缺陷,就是隻能返回第一個節點,因為成功匹配第一個節點的時候,就結束並返回節點了。若要實現 querySelectorAll 的效果,則還需要對它進行改進。

解決過程

由於我對 jQuery 並不熟悉,可能因此導致我搜尋的時候花的時間比較長。所以寫一下我的搜尋過程,可能會有啟發。
我先後搜尋的關鍵詞是這樣變化的,一開始根本不知道該用什麼詞去描述這個問題,到最後才定位準確。

關鍵詞變化路徑

  • 原生 JavaScript 定位 屬性 標籤
  • 原生 JavaScript 根據 屬性
  • JavaScript 根據 屬性 標籤
  • JavaScript 根據 屬性 節點
  • JavaScript 根據 自定義 屬性 節點
  • JavaScript 自定義 屬性 節點
  • jquery 選擇器 屬性 自定義
  • jquery 選擇器 屬性 自定義 原始碼
  • jquery selector 屬性 自定義 原始碼

在這裡我企圖去檢視 jQuery 的原始碼來看它是怎麼實現的(未遂),查到 jQuery 的選擇器是使用 Sizzle 引擎這一層就又轉換關鍵詞了。

  • JavaScript 自定義 屬性 篩選 DOM
  • JavaScript 自定義 屬性 篩選 節點
  • JavaScript 自定義 屬性 查詢 節點
  • jQuery 選擇器 原生 JavaScript
  • jQuery 選擇器 原生 JavaScript 自定義 屬性
  • 選擇器 原生 JavaScript 自定義 屬性

在這裡我知道了 jQuery 裡用屬性篩選元素的用法叫做“屬性過濾選擇器”,於是:

  • 原生 JavaScript 屬性過濾選擇器
  • 原始碼 屬性過濾選擇器
  • 屬性過濾選擇器 原生
  • 屬性過濾 選擇器 原生 JavaScript

最後不得已試了試英文……一招定位到了 StackOverflow 。

  • find element pure javascript attribute

最後記錄一下上面這一些不靠譜的關鍵詞得到的一些不錯的東西:

http://youmightnotneedjquery.com/ —— 列舉了一些可以用原生 JavaScript 替代 jQuery 的程式碼
sizzle.js 原始碼
Sizzle 文件
jQuery-1.9.1原始碼分析系列(三) Sizzle選擇器引擎——詞法解析

總結

根據我這次的搜尋過程,下次遇到問題的時候首選英文搜尋是比較靠譜的辦法,這樣做的好處有:

  1. StackOverflow 是以問題為驅動的,所以採用描述性的詞也容易定位。
  2. 專業詞彙的問題,有時對一些詞彙存在盲點,往往不知道自己的問題如何表述,這時 StackOverflow 的優勢就出來了。

相關文章