我正在https://youmightnotneedjquery.com/#remove_class學習代碼:
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(new RegExp('(^|\\b)' className.split(' ').join('|') '(\\b|$)', 'gi'), ' ');
我只是想知道為什么要使用 RegExp 來執行替換?為什么不使用更簡單的版本,如下所示:
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(className, ' ');
更新 我認為第一個版本有一個錯誤。HTML 類名區分大小寫,請參閱CSS 選擇器中的類名是否區分大小寫?,因此不應在 RegExp 中使用標志“i”。
uj5u.com熱心網友回復:
因為您可以有一個包含指定類作為子字串的類。
假設您有一個元素 with并且想要洗掉abc. 您的代碼將替換第一個abc,因此它將更改為而不是。
uj5u.com熱心網友回復:
無論是在一般情況下還是在特定示例中,這看起來都不是一個好方法。
該正則運算式似乎旨在允許傳遞以空格分隔的類名串列的字串,而不是像使用HTMLElement.classList.remove(). 如果您嘗試將包含空格的字串傳遞給HTMLElement.classList.remove()它,則會拋出一個DOMException.
我認為您在該網站上找到的正則運算式方法不會按預期作業。讓我們看一下幾個示例輸入字串,以及生成的正則運算式:
string: 'class-a'
regex: /(^|\b)class-a(\b|$)/gi
這個正則運算式非常清楚,它首先查找字串的開頭或分詞符,然后是字串“class-a”,然后是分詞符或字串的結尾。
因為這行代碼包含className.split(' '),看起來它是為了處理包含空格字符的字串。像這樣:
string: 'class-a class-b'
regex: /(^|\b)class-a|class-b(\b|$)/gi
但是,因為它沒有將正則運算式的類名部分包裝在方括號中以創建自己的組,所以它最終是上面的。該正則運算式被該|字符從中間拆分,并尋找兩個匹配項:
- 字串的開頭或分詞符,后跟“class-a”。
- “class-b”后跟一個單詞中斷或字串的結尾。
這意味著它將匹配它不應該用于 classList 這樣的類class-a2 thisclass-b。
還有另外幾個問題。CSS 類區分大小寫,因此使用不區分大小寫的正則運算式是沒有意義的。此外,正則運算式試圖用于\b檢測 CSS 類名的開頭或結尾,但\b也會匹配字母和連字符之間的邊界,因此字串'class-a-1'將匹配正則運算式/(^|\b)class-a(\b|$)/。
相反,您最好使用 將元素的 classList 字串轉換為單個類的陣列split(' '),然后在該字串陣列中找到您的類并使用類似的方法將其洗掉Array.prototype.splice,然后將該陣列重新加入一個 classList 字串并覆寫舊的一。像這樣的東西:
if (el.classList) {
el.classList.remove(className);
} else {
let classes = el.className.split(' ');
let classIndex = classes.indexOf(className);
if (classIndex !== -1) {
classes.splice(classIndex, 1);
}
el.className = classes.join(' ');
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/340852.html
標籤:javascript 正则表达式
