在匹配类时,jQuery用于一种相对笨拙的方法,无论是目标节点的类名,还是表达式都要进行处理才能用。
match = " " + match[1].replace(/\\/g, "") + " "; for (var i = 0, elem;(elem = curLoop[i]) != null; i++) { if ((elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0)) { //******************* } }
如果是match为.aaa还好,只用进行一次过滤,如果match为.aaa.bbb呢?!那么有没有更快的方法呢?有的。我们需要构造一个强大的正则出来,让它能同时匹配我们所需要的类名,可能是一个,也可能是多个,并且不分次序。拜群里的高手所赐了,这正则很快就解决了(我为我这个强大的智囊团而骄傲,从此不用上51js,javaeye,blueidea了……)。
<ul> <li class="aaa bbb">符合</li> <li class="bbb aaa">符合</li> <li class="aaa ccc bbb">符合</li> <li class="aaa">不符合 </li> <li class="bbb">不符合 </li> </ul>
比如,我们想匹配同时拥有aaa与bbb的这些LI元素,就要只需要把表达式转换成正则,直接test验证就行了,无需再对元素上的className进行处理。
var src = "" var escape = /([-.*+?^${}()|[\]\/\\])/g "aaa.bbb".replace(/[^.]+/g,function($){ src += '(?=[\\s\\S]*(?:^|\\s)'+$.replace(escape, '\\$1')+'(?:\\s|$))' }) var reg = new RegExp(src); var t1 = "aaa bbb" var t2 = "bbb aaa" var t3 = "aaa ccc bbb" var t4 = "aaa" var t5 = "bbb" alert(reg.test(t1))//true alert(reg.test(t2))//true alert(reg.test(t3))//true alert(reg.test(t4))//false alert(reg.test(t5))//false
2011.1.27更好的方案
var src = ".aaa.bbb".replace(/([\/\[\]\:])/g,'\\$1')//替换className中允许的特殊字符 .replace(/\.([^.]+)/g,'(?=[\\s\\S]*(?:^|\\s)$1(?:\\s|$))');//匹配 var reg = new RegExp('^'+src);//加了^就匹配开头,不然发现不匹配还要找其他n个位置(n是字符串长度) by abcd var t1 = "aaa bbb" var t2 = "bbb aaa" var t3 = "aaa ccc bbb" var t4 = "aaa" var t5 = "bbb" alert(reg.test(t1))//true alert(reg.test(t2))//true alert(reg.test(t3))//true alert(reg.test(t4))//false alert(reg.test(t5))//false