JavaScript通過HTML的class來獲取HTML元素的方法總結


JavaScript通過HTML的class來獲取HTML元素的方法總結

除了getElementsByClassName()函數,我們可以自己動手編寫程式來通過class獲取元素,接下來我們整理了一下JavaScript通過HTML的class來獲取HTML元素的方法總結,需要的朋友可以參考下
 

對於js來說,我想每一個剛接觸它的人都應該會抱怨:為什么沒有一個通過class來獲取元素的方法。盡管現在高版本的瀏覽器已經支持getElementsByClassName()函數,但是對於低版本瀏覽器來說,還是無法兼容,在脫離其他庫的時候,還是得自己封裝一個方法。

方法一

11     
12 function getByClass1(parent, cls){
13   var res = [];  //存放匹配結果的數組
14   var ele = parent.getElementsByTagName('*');
15   for(var i = 0; i < ele.length; i++){
16     if(ele[i].className == cls){
17       res.push(ele[i]);
18     }
19   }
20   return res;
21 }

 

當然class里的值只有一個時,上面的方法沒問題,但當值為多個時,就會出現問題。

1 <div class="test"></div>
2 <div class="test box"></div>
3 <script>
4   getByClass1(document, 'test');  //只獲取到第一個div
5 </script>

方法二

出現問題的時候,我們會嘗試着改進,對於多類名的情況我們可以用正則去匹配是否包含所要查找的class名,於是就出現了下面這種寫法:

 1 function getByClass2(parent, cls){
 2   var res = [];
 3   var reg = new RegExp('\\b' + cls + '\\b', 'i');  //匹配cls是一個獨立的單詞
 4   var ele = parent.getElementsByTagName('*');
 5   for(var i = 0; i < ele.length; i++){
 6     if(reg.test(ele[i].className)){
 7       res.push(ele[i]);
 8     }
 9   }
10   return res;
11 }

 

 

這種方法看似可以,解決了getByClass1()的問題,我也用了好長一段時間,但是還會有一個隱藏的bug。看下面的例子:

1 <div class="test"></div>
2 <div class="test_box"></div>
3 <div class="test-box"></div>
4 <script>
5   getByClass2(document, 'test');  //結果獲取到了第一個div和第三個div
6 </script>  

 

理論上應該只獲取到第一個,但是卻和我們預期不一樣。這個bug源於下面這段代碼里的\b

  var reg = new RegExp('\\b' + cls + '\\b', 'i'); 

我們先來看下\b在正則中的表示的意思

\b是正則表達式規定的一個特殊代碼,代表着單詞的開頭或結尾,也就是單詞的分界處。

通俗點說:\b就是匹配一個單詞(從左邊界到右邊界)。

而問題也就出在這里,\b把除字母、數字、下划線外的其他字符都當成是邊界,對於上面的例子中第三個class值為test-box,\b匹配時,把連字符(-)當作單詞邊界,所以也匹配了第三個div。

方法三

因此我們還需要對上面方法進行進一步改進,這里參考了stackoverflow上提到的一種方法:

How to Get Element By Class in JavaScript?

改進后的代碼如下:

function getByClass3(parent, cls){
  var res = [];
  var reg = new RegExp(' ' + cls + ' ', 'i');  //匹配cls時,兩邊需要有空格
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(reg.test(' ' + ele[i].className + ' ')){
      res.push(ele[i]);
    }
  }
  return res;
}

 

這種方法舍去了用\b而采用空格來匹配邊界,先在獲取到的className值兩邊加上空格,這樣就保證了className里的每個值兩邊都會有空格,然后再用正則去匹配。

用這種方法暫時還未發現問題,但是使用時,方法中的單引號內的空格一定不能落下。

方法四

function getByClass3(parent, cls){
  var res = [];
  var reg = new RegExp('(^|\\s)' + cls + '($|\\s)', 'i');
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(reg.test(ele[i].className)){
      res.push(ele[i]);
    }
  }
  return res;
}

 

空格完全用正則來處理,這樣省去了空格容易落下的問題,代碼也更美觀精簡。

那么這種方法是否就是比較完美的呢,其實不然,下面來看下更優的方案。

方法五(完美版)

文章開頭已經提到,高版本的瀏覽器已經支持getElementsByClassName()方法。出於性能考慮,對支持的瀏覽器使用原生方法勢必會更好。而對於低版本的瀏覽器使用上面的方法四。

function getByClass(parent, cls){
  if(parent.getElementsByClassName){
    return parent.getElementsByClassName(cls);
  }else{
    var res = [];
    var reg = new RegExp(' ' + cls + ' ', 'i')
    var ele = parent.getElementsByTagName('*');
    for(var i = 0; i < ele.length; i++){
      if(reg.test(' ' + ele[i].className + ' ')){
        res.push(ele[i]);
      }
    }
    return res;
  }
}

當然方法五自認為是相對較好的方案,如果有更優秀的方法歡迎留言補充。

如對本文有疑問,請提交到交流社區,廣大熱心網友會為你解答!! 點擊進入社區

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM