国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript通過HTML的class來獲取HTML元素的方法總結(jié)

2019-11-20 09:55:41
字體:
供稿:網(wǎng)友

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

方法一

function getByClass1(parent, cls){  var res = [];  //存放匹配結(jié)果的數(shù)組  var ele = parent.getElementsByTagName('*');  for(var i = 0; i < ele.length; i++){    if(ele[i].className == cls){      res.push(ele[i]);    }  }  return res;}

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

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

方法二

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

function getByClass2(parent, cls){  var res = [];  var reg = new RegExp('//b' + cls + '//b', '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;}

這種方法看似可以,解決了getByClass1()的問題,我也用了好長一段時間,但是還會有一個隱藏的bug??聪旅娴睦樱?/p>

<div class="test"></div><div class="test_box"></div><div class="test-box"></div><script>  getByClass2(document, 'test');  //結(jié)果獲取到了第一個div和第三個div</script>  

理論上應(yīng)該只獲取到第一個,但是卻和我們預(yù)期不一樣。這個bug源于下面這段代碼里的/b

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

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

/b是正則表達式規(guī)定的一個特殊代碼,代表著單詞的開頭或結(jié)尾,也就是單詞的分界處。

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

而問題也就出在這里,/b把除字母、數(shù)字、下劃線外的其他字符都當成是邊界,對于上面的例子中第三個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里的每個值兩邊都會有空格,然后再用正則去匹配。

用這種方法暫時還未發(fā)現(xiàn)問題,但是使用時,方法中的單引號內(nèi)的空格一定不能落下。

方法四

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;}

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

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

方法五(完美版)

文章開頭已經(jīng)提到,高版本的瀏覽器已經(jīng)支持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;  }}

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 孝感市| 红河县| 香格里拉县| 米脂县| 南和县| 镇坪县| 内丘县| 南涧| 赣榆县| 南溪县| 蒙自县| 桦川县| 沛县| 潮安县| 海南省| 巢湖市| 盐边县| 晋中市| 巧家县| 西华县| 乌什县| 安徽省| 安宁市| 崇仁县| 洮南市| 理塘县| 中江县| 沅陵县| 浦北县| 嵩明县| 南充市| 盈江县| 阳高县| 瑞昌市| 台北市| 萝北县| 弋阳县| 密山市| 磐石市| 深州市| 威信县|