2025-04-23

preface

昨晚在看《javascript權威指南》後,看見作者自己封裝一個兼容所有瀏覽器的山寨HTML5新API classLIst類。自己想瞭想覺得自己也要去玩一下,但是能力還是有限,所以就遇見一個正則表達式的bug,確實自己對正則表達式有興趣但是掌握不是很好。困擾瞭一段時間,早上在stack overflow網站中找到瞭答案。

issue description

首先我創建一個類叫CSSClassList

CSSClassList = function(el){

this.el = typeof el==”object”?el:document.getElementById(el);

}
然後就在CSSClassList原型中添加方法,我模仿classList類中的contains(check if an element’s list of classes contains a specific class),這個方法是用來檢查該元素有沒包含指定的類選擇器。

CSSClassList.prototype.contains = function(cls) {

var classname = this.el.className, reg = new RegExp(“\b” + cls + “\b”);

return reg.test(classname);

}

然後就出問題,你可以試一下,我就不想貼出我的HTML和CSS瞭,問題就在於你要查詢的元素用contains測是否包含指定類選擇器都是為false的,無論該元素是否包含。為什麼呢?昨天晚上就在這裡栽瞭。

debug

我把我的目標放在正則表達式上,我在想是不是我的正則表達式寫錯瞭

1 在contains方法中console.log出reg結果:比如我傳給contains函數的實參是為”font”,那麼console.log出來的是/font/心裡活動: 看到這個答案我就鬱悶下,這樣子應該是可以匹配的到的呀2 在contains方法中return後面的reg改成/font/,就變成瞭/font/.test(classname)結果:返回的是true心裡活動:什麼情況,奇葩javascript你在幹什麼啊!!心中更加鬱悶3 在contains方法中的new RegExp(“\b” + cls + “\b”)改成new RegExp(cls)結果:返回的是true心裡活動:啊!好像找到問題所在瞭,是字符串中的\b問題4 用google搜索stackoverflow相關問題結果:Javascript RegExp and boundaries心裡活動:總算讓我知道原因所在瞭。

summary

“\b” 這個在javascript解析器中它會解釋為退格鍵,我們知道退格鍵的ASCII碼是8。我們可以這樣子來測試下:”\b”.charCodeAt(0) == 8 結果是為true”\\b” \是用來阻止javascript解析器把”\b”解析成退格鍵,可以用同樣的方法來測試下”\\b”.length “\\b”.charCodeAt(0) “\\b”.chatCodeAt(1)分別為2 92 98new RegExp(“\\b”+cls+”\\b”)用console.log打印出來是,假如我的cls為”font”,打印結果為”\bfont\b”,而之前那個new RegExp(“\b”+cls+”\b”)打印出來的是”(退格鍵)font(退格鍵)”,但是在這個單詞左右還有兩個退格鍵,所以我匹配不瞭”font”。這個是本文的重點

last

CSSClassList.prototype.contains = function(cls) {

var classname = this.el.className, reg = new RegExp(“\\b” + cls + “\\b”);

return reg.test(classname);

}

reference

Javascript RegExp and boundaries

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *