queryspeed
QuerySpeed.js
(function(){
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
}
}
var mix = function(target, source ,override) {
var i, ride = (override === void 0) || override;
for (i in source) {
if (ride || !(i in target)) {
target[i] = source[i];
}
}
return target;
}
var dom = {};
var metaObject = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
},
_startOfHTML = "\t__views.push(",
_endOfHTML = ");\n",
_rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g;
(function(w,s){
//http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
s = ["XMLHttpRequest",
"ActiveXObject('Msxml2.XMLHTTP.6.0')",
"ActiveXObject('Msxml2.XMLHTTP.3.0')",
"ActiveXObject('Msxml2.XMLHTTP')",
"ActiveXObject('Microsoft.XMLHTTP')"];
if( !-[1,] && w.ScriptEngineMinorVersion() === 7 && location.protocol === "file:"){
s.shift();
}
for(var i = 0 ,el;el=s[i++];){
try{
if(eval("new "+el)){
dom.xhr = new Function( "return new "+el)
break;
}
}catch(e){}
}
})(this);
mix(dom,{
queryId : function (id, context) {
var el = (context || document).getElementById(id);
return el && [el] || []
},
queryTag : function(tag,context){
var flag_skip = tag !== "*",result = [],els = (context || document).getElementsByTagName(tag);
if(-[1,]){
return Array.prototype.slice.call(els)
}else{
for(var i = 0,ri = 0,el;el = els[i++];)
if(flag_skip || el.nodeType === 1){
result[ri++] = el
}
}
return result;
},
each: function(array,fn,bind){
for (var i = 0, n = array.length; i < n; i++){
if(i in array){
if(fn.call(bind, array[i], i, array) === false){
break;
}
}
}
},
numberOfWindow : 0,
numberOfIframe : 0,
hasReady : function(){
if(dom.numberOfWindow === dom.numberOfIframe ){
var el = dom.queryId("hasReady")[0]
el.innerHTML = "已经准备就绪!";
el.style.color = "#a9ea00";
}
},
addEvent: document.addEventListener ? function(el,type,fn){
el.addEventListener(type,fn,false);
} : function(el,type,fn){
el.attachEvent("on"+type,function(){
return fn.call(el,window.event)
})
},
quote: String.quote || function (str) {
return '"' + str.replace(/[\\\"\x00-\x1f]/g, function (a) {
var c = metaObject[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"'
},
ejs_partial: function(url){
var xhr = dom.xhr();
xhr.open("GET",url,false);
xhr.setRequestHeader("If-Modified-Since","0");
xhr.send(null);
return xhr.responseText|| ""
},
ejs: function(obj,usePart){
if(!usePart){//如果普通模板,则要整理配置文件
obj.left = obj.left || "<&";
obj.right = obj.right || "&>";
obj.rLeft = obj.rLeft || new RegExp("\\s*"+ obj.left+"\\s*");
obj.rRight = obj.rRight || new RegExp("\\s*"+ obj.right+"\\s*");
}
//取得缓存索引
var key = obj.selector || obj.url,
rAt = _rAt,
startOfHTML = _startOfHTML,
endOfHTML = _endOfHTML,
self = arguments.callee,
buff = ["var __views = [];\n"],str;
if(obj.selector){
var el = dom.queryId(key);
if (!el.length) throw "can not find the target element";
str = el[0].text;
}else {
str = dom.ejs_partial(obj.url);
if (!str) throw "the target file does not exist";
}
if(!self[key]){
var arr = str.trim().split(obj.rLeft),temp = [],url,selector,i=0,n=arr.length,els,segment,logic;
while(i<n){
segment = arr[i++];
els = segment.split(obj.rRight);
if(segment.indexOf(obj.right) !== -1){//这里不使用el.length === 2是为了避开IE的split bug
switch (els[0].charAt(0)) {
case "~"://include 局部模板 以URL方式引入
delete obj.selector;
obj.url = els[0].substring(1).trim();
self[url] = self[url] || self(obj,true);
temp = temp.concat(self[url] );
break;
case ":"://include 局部模板 以元素选择符方式引入
delete obj.url;
selector = obj.selector = els[0].substring(1).trim();
self[selector] = self[selector] || self(obj,true);
alert(temp)
temp = temp.concat(self[selector] );
break;
case "="://处理后台返回的变量(输出到页面的);
logic = els[0].substring(1);
if(logic.indexOf("@") !== -1){
temp.push(startOfHTML, logic.replace(rAt,"$1data."), endOfHTML);
}else{
temp.push(startOfHTML, logic, endOfHTML);
}
break;
case "#"://处理注释
break;
default:
logic = els[0];
if(logic.indexOf("@") !== -1){
temp.push(logic.replace(rAt,"$1data."), "\n");
}else{
temp.push(logic, "\n");
}
}
els[1] && temp.push(startOfHTML, dom.quote.call(null,els[1]), endOfHTML)
}else{
temp.push(startOfHTML, dom.quote.call(null,els[0]), endOfHTML)
}
}
if(usePart){//局部模板
return (self[key] = temp);
}else{
//缓存模板函数
self[key] = new Function("data", buff.concat(temp).join("") + ';return __views.join("");');
}
}
return self[key](obj.data || {});
}
});
window.dom = dom;
//要测试的框架
var frameworks = {
"Peppy 0.1":{
disable:1,
file:"peppy.js",
fun:"$"
},
"uuQuery v1.01":{
file:"uuQuery.js",
fun:"uuQuery"
},
"DOMAssistant2.8":{
disable:1,
file:"DOMAssistantComplete-2.8.js",
fun:"$"
},
"query v3.9":{
file:"queryv39.js",
fun:"dom.query"
},
"Fox":{
disable:1,
file:"Fox.js",
fun:"Fox.query"
},
"jQuery1.4.4":{
disable:1,
file:"jquery1.4.4.js",
fun:"jQuery"
},
"Sizzle":{
file:"sizzle.js",
fun:"Sizzle"
},
"Sly v1.0rc2":{
disable:1,
file:"Sly.js",
fun:"Sly.search"
},
"inQuery":{
disable:1,
file:"inCore.js,inQuery.js",
fun:"$"
},
"EXT 2.2":{
disable:1,
file:"ext-2.2.js",
fun:"Ext.query"
},
"JQuery 1.2.6":{
disable:1,
file:"jquery-1.2.6.js",
fun:"jQuery"
},
"MooTools 1.3":{
disable:1,
file:"mootools.js",
fun:"$$"
},
"YUI 2.6.0":{
disable:1,
file:"YUI-2.6.0.selector-beta.js",
fun:"YAHOO.util.Selector.query"
},
"myframework":{
disable:1,
file:"myFramework.js",
fun:"getElements"
},
"Dojo 1.2.0":{
disable:1,
file:"dojo-1.2.0.js",
fun:"dojo.query"
}
}
//要测试的选择器
var selectors = [
"div :only-of-type",
"th:first-of-type",
"th:last-of-type",
"td:nth-of-type(even)",
"td:nth-last-of-type(odd)",
"body :empty",
"div:not(.example)",
"p:contains(selectors)",
"div p a",
// "div, p, a",
"div p",
"body div",
".note",
"ul.toc li.tocline2",
"ul.toc > li.tocline2",
"tr .pattern",
"p",
"div",
"div ~ p",
"div > div",
"div ~ div",
"div > p",
"body",
"div + p",
"div ~ p",
"div[class^=exa][class$=mple]",
"div.example",
"ul .tocline2",
"div.example, div.note",
"#title",
"h1#title",
"div #title",
"h1#title + div > p",
"a[href][lang][class]",
"div[class]",
"div[class=example]",
"div[class^=exa]",
"div[class$=mple]",
"div[class*=e]",
"div[class|=dialog]",
"div[class!=made_up]",
"div[class~=example]",
"p:nth-child(even)",
"p:nth-child(2n)",
"p:nth-child(odd)",
"p:nth-child(2n+1)",
"p:nth-child(n)",
"p:only-child",
"p:last-child",
"p:first-child",
"div :only-child",
"td:odd",
"p:even"
]
window.onload = function(){
dom.queryId("iframes_tc")[0].innerHTML = dom.ejs({
selector:"iframes_tmpl",
data:{
frameworks:frameworks
}
});
dom.queryId("table_tc")[0].innerHTML = dom.ejs({
selector:"table_tmpl",
data:{
frameworks:frameworks,
selectors:selectors
}
});
var tbody = dom.queryTag('tbody')[0];
var tfoot = dom.queryTag('tfoot')[0];
var lastrow = dom.queryTag('tr',tfoot)[0];
var startTest = dom.queryId("startTest")[0];
var stopTest = dom.queryId("stopTest")[0];
var scoreNum= {}; //用于放置积分
var scoreTds = {};//用于放置存在积分的TD元素
var cellIndex = 1;
var framework;
for(var name in frameworks){
framework = frameworks[name];
if (!framework.disable){
framework.window = window.frames[name];
framework.selectors = selectors.concat();
scoreTds[name] = lastrow.cells[cellIndex++]
dom.numberOfWindow++;
scoreNum[name] = 0;
}
}
var tests = [] ,rows = tbody.rows
dom.each(selectors, function(selector, i){//构建测试单元数组,个数为tbody的TD数
var cellIndex = 1,row = rows[i],framework;
for (var name in frameworks){
framework = frameworks[name];
if (!framework.disable){
tests.push({
'window': framework.window,//执行环境
'selector': framework.selectors[i],
'name': name,
'row': row,
'cell' : row.cells[cellIndex++]
});
}
}
});
var timeoutId;
var testRunner = function(){
var test = tests.shift();//取得测试单元
if (!test || !test.window.test) return;//如果不存在选择器函数返回
var results = test.window.test(test.selector);
test.cell.className = 'test';
test.cell.innerHTML = results.time + ' ms | ' + results.found + ' found';//花了多少时间与发现了多少个节点
test.cell.speed = results.time;
if (results.error){
test.cell.innerHTML = results.time + ' ms | <span class="exception" title="' + results.error + '">error returned</a>';
test.cell.className += ' exception';
test.cell.found = 0;
test.cell.error = true;
} else {
test.cell.found = results.found;
test.cell.error = false;
}
scoreNum[test.name] += test.cell.speed;
scoreTds[test.name].innerHTML = ' ' + scoreNum[test.name] + ' ';
if (test.cell == test.row.lastChild) colourRow(test.row);
timeoutId = setTimeout(testRunner, 300);
};
//为Tbody的行着色
var colourRow = function(row){
var cells = row.cells
var speeds = [];//用于存在速度
dom.each(cells,function(cell,i){
speeds[i] = cell.error ? 9999999999 : ~~cell.speed;
});
var min = Math.min.apply({}, speeds);
var max = Math.max.apply({}, speeds);
var consistency = true;
var found = [];
dom.each(cells, function(cell, i){
if (!cell.error && "found" in cell ){
found.push(cell.found);
var length = found.length;
if(length > 2 && found[length-2] !== found[1-1] ){
return (consistency = false);
}
}
if (cell.speed == min) cell.className += ' good';
else if (cell.speed == max) cell.className += ' bad';
else cell.className += ' normal';
});
if (!consistency){//如果各个框架取得的结果不一致,则全部
dom.each(cells, function(cell){
if (cell.found != undefined) cell.className += ' mismatch';
});
}
};
dom.addEvent(startTest,"click",testRunner);
dom.addEvent(stopTest,"click",function(){
clearTimeout(timeoutId);
timeoutId = null;
});
}
}).call(this);
index.html
QuerySpeed~选择器测试速工具
template.html的javascript部分
var params = document.location.search.slice(1).split('&'), i = 0,pair, queryFnStr
while((pair = params[i++])){
if(pair.indexOf("include")!==-1){
document.write('<script type="text/javascript" src="frameworks/'+pair.replace("include=","")+'"></sc'+'ript>')
}
if(pair.indexOf("function")!==-1){
queryFnStr = pair.replace("function=","")
}
}
window.test = function(selector){
try {
var start = new Date() - 0
var queryFn = arguments.callee.queryFn;
var nodes = queryFn(selector);
var time = new Date - start;
return {'time': time, 'found': nodes.length};
} catch(err){
return {'time': time||1, 'found': -1, 'error': err};
}
};
(function(){
try{
var queryFn = eval("window."+queryFnStr);
// window.console.log(queryFnStr+"准备好了")
queryFn("body")
test.queryFn = queryFn;
}catch(e){
setTimeout(arguments.callee,64)
}
})();
window.onload = function(){
window.parent.dom.numberOfIframe++;
window.parent.dom.hasReady();
}
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
浙公网安备 33010602011771号