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
- var classname = this.el.className, reg = new RegExp(“\\b” + cls + “\\b”);
- var classname = this.el.className, reg = new RegExp(“\b” + cls + “\b”);
- this.el = typeof el==”object”?el:document.getElementById(el);