className的高效匹配

在匹配类时,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
原文地址:https://www.cnblogs.com/rubylouvre/p/1945835.html