正規表達式自己有test
和exec
二個方法,搭配字串的match
,search
, replace
等方法,可以有強大的功能。
<div class="foo bar"></div>
<div class="bar foo"></div>
<div></div>
<span class="foo bar baz"></span>
<script>
function findClassInElements(className, type) {
const elems = document.getElementsByTagName(type || "*");
const regex = new RegExp("(^|\\s)" + className + "\\s|$");
const results = [];
for (let i = 0; i < elems.length; i++) {
if (regex.test(elems[i].className)) {
results.push(elems[i]);
}
}
return results;
}
console.log(findClassInElements("foo", "div").length); // 2
console.log(findClassInElements("foo", "span").length); // 1
console.log(findClassInElements("foo").length); // 3
</script>
這裡我們自建一個 HTML 搜尋器,可以找出頁面上有指定 class name 的 HTML 元素。
我們先用getElementsByTagName
抓取指定的 HTML 標籤,如果沒有這個參數的話就抓頁面上全部元素,存在elems
的陣列裡。
然後我們根據參數裡的 class name 建立正規表達式。Class name 是寫在 HTML 元素的class
屬性裡,但是我們不能確定它的順序,不過可以歸納出這些規則:
事實上只是 class name 前後有沒有空格的問題,所以正規表達式就是"(^|\\s)" + className + "\\s|$"
。又因為 class name 要等到函式被呼叫時才會知道,正規表達式就不能用實質方式建立,必須用new RegExp()
動態產生,此時規則要以字串方式代入。我們又用了\s
代表空白符號,反斜線在字串裡出現代表要 escape 緊跟在後的字元,但是我們要保留\s
當中的反斜線,所以要在前面加上反斜線來 escape 它。這是用字串建立正規表達式比較麻煩的地方。
接著建一個空陣列來保管等一下匹配到的結果。
我們將elems
陣列裡的 HTML 元素丟進迴圈裡,檢查每個元素的className
是否匹配我們的正規表達式。在這裡使用正規表達式的test
方法,如果有匹配到會回傳true
,反之回傳false
。將有匹配到的元素存進results
陣列裡。