Icarus是我目前匹配精度最高(通过470个单元测试保证精度),速度最快(IE67下力压jQuery,其他浏览器都是使用querySelectorAll不分上下)的选择器,并且它全面支持CSS3的所有新增伪类,支持jQuery所有自定义伪类,并且支持对XML的查找,支持XML带命名空间的元素的查找(jQuery只能支持不带命名空间的,并且非常容易报错)。
Icarus与jQuery1.7在slickspeed中的速度比赛结果(数值最大代表越慢):
Icarus | jQuery1.7 | 比率 | |
IE7 | 443 | 657 | 1.5 |
IE6 | 975 | 1570 | 1.6 |
如果对比早期的jQuery.42就更不用说了,是其两倍以上。
Icarus最大亮点是对XML的完美支持,为此它用得到xpath与getElementsByTagName,对于命名空间的支持,请使用”aaa\\:bbb”方式来查找。
以下就是Icarus用到原生查找API:
- getElementById
- getElementsByTagName
- getElementsByTagNameNS
- getElementsByClassName
- evaluate (xpath)
- selectNodes (xpath)
- querySelectorAll
Icarus的代码量为930行(不依赖dom的其他模块),jQuery的Sizzle为1500行。
Icarus对CSS3伪类是按W3C的规范来查找,比如:not反选伪类,只支持单个表达式,如div:not(.a),不能用div:not(.a.b),要用就需要多个的反选,div:not(.a):not(.b)。
Icarus虽然支持jQuery的自定义伪类,但并不提倡使用,如位置伪类(:first,:last,:even,:odd,:eq…),我们完全可以使用标准的子元素过滤伪类要代替(:last-child,:first-child,:nth-child(even)…),对于jQuery的自定义表单伪类(:text,:radio….),我们也完全可以使用属性选择器来代替(input[type=text],input[type=radio]….)。总之,不标准的东西活不长,希望大家切记。
下面是Icarus对命名空间的支持演示,例子是inline SVG,由于IE9不支持,请在高版本的标准浏览器中看。在IE10支持SVG后,SVG的应用就大大增多了,因此命名空间的支持是必须的。
< html xmlns = "http://www.w3.org/1999/xhtml" xmlns:svg = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" > < head > < title >icarus svg by 司徒正美</ title > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < script > window.onload = function(){ alert(dom.query("svg\\:feOffset:first")[0].tagName) } </ script > </ head > < body > < svg:svg height = "0" > <!-- Create the filter. Make sure it uses the sRGB colorspace or you're in for some nasty surprises. --> < svg:filter color-interpolation-filters = "sRGB" id = "perspDisp" filterUnits = "userSpaceOnUse" x = "0%" y = "0%" width = "512" height = "512" > <!-- Move the video 128px to the bottom/right so that the displacement filter can reach 128px to the top/left without reaching beyond the image --> < svg:feOffset x = "128" y = "128" width = "256" height = "256" dx = "128" dy = "128" result = "displacement" /> <!-- This actually loads our texture--> < svg:feImage id = "textureLoader" x = "0" y = "0" width = "256" height = "256" xlink:href = "texture.tinman.png" /> <!-- Tile the texture to fill the whole viewport so that the displacement filter can also reach 128px to the bottom/right without leaving the texture --> < svg:feTile x = "0" y = "0" width = "512" height = "512" result = "texture" /> <!-- Apply the displacement --> < svg:feDisplacementMap x = "128" y = "128" width = "256" height = "256" in = "texture" in2 = "displacement" scale = "255" xChannelSelector = "R" yChannelSelector = "G" /> <!-- Apply the alpha of the displacement map to the final image, so that whatever is transparent in the map is also transparent in the final image --> < svg:feComposite in2 = "displacement" operator = "in" /> <!-- Move the image back to the top/left --> < svg:feOffset x = "0" y = "0" width = "256" height = "256" dx = "-128" dy = "-128" /> </ svg:filter > </ svg:svg > </ body > </ html > |
后话,javascript的选择器基本是为了兼容IE678(IE8的querySelectoAll支持种类太少),以后的选择器基本上是用querySelectorAll与evaluate与matchesSelector来写了,CSS4也很快到来了,带来更多伪类,因此jQuery的自定义伪类基本没有存在的必要。