querySelector用法改进
原来选择器只支持一个上下文,并对IE8的BUG进行了规避
if (!flag_xml && doc.querySelectorAll) {//FF,opera,chrome,safari的XML文档也实现了querySelectorAll接口,但不能用
var query = expr;//IE的getElementsByTagName,querySelectorAll对OBJECT元素的孩子的查找都存在问题
if( doc.documentMode === 8 && context.nodeType === 1 && context.nodeName.toLowerCase() !== "object"){
var id = context.getAttribute( "id" ),uid = context.uniqueID//IE8在上下文为元素节时,搜索结果包含自己
if ( !id ) {
context.setAttribute( "id", uid );
}
try {
return pushResult(context.querySelectorAll( "#" + uid + " " + query ),result,flag_multi);
} catch(e) {
} finally {
if ( id == context.uniqueID ) {
context.removeAttribute( "id" );
}
}
}else{
if(/\!\=/.test(query))//手动支持 E[Attr!=Val]
query = query.replace(/\[\s*(\w+)\s*!=\s*((['"]*).*?\3)\s*\]/g,":not([$1=$2])");
try {
return pushResult( context.querySelectorAll(query) ,result,flag_multi);
} catch(e) {}
}
}
改进如下,现在只需规避IE的OBJECT bug。
if (!flag_xml && doc.querySelectorAll) {//http://www.w3.org/TR/selectors/
node = context;//使用替身,以便在多上下文实现不重排查找
var useContains = false;
if(contexts.length > 2 || doc.documentMode === 8 && context.nodeType === 1){
node = doc;
useContains = true;
}
if(doc.documentMode !== 8 || node.nodeName.toLowerCase() !== "object"){
try{
nodes = pushResult( node.querySelectorAll(expr) ,result,flag_multi);
var ret = []
if(useContains && nodes.length){
var cn = contexts.length;
for(i = 0, ri = 0; i < nodes.length; i++){
inner:
for(var c = 0; c < cn; c++){
if(dom.contains(contexts[c], nodes[i])){
ret.push(nodes[i])
break inner;
}
}
}
return ret;
}
return result;
}catch(e){}
}
}
另一种改进是,通过对元素节点的上下文添加一个类名,这样查找就可以一步到位。不足之处就是前前后后要对类进行操作。
if (!flag_xml && doc.querySelectorAll) {
var query = expr;
if(contexts.length > 2 || doc.documentMode == 8 && context.nodeType == 1 ){
if(contexts.length > 2 )
context = doc;
query = ".fix_icarus_sqa "+query;//IE8也要使用类名确保查找范围
for(i = 0; node = contexts[i++];){
if(node.nodeType === 1){
node.className = "fix_icarus_sqa " + node.className;
}
}
}
if(doc.documentMode !== 8 || context.nodeName.toLowerCase() !== "object"){
try{
result = pushResult( context.querySelectorAll(query) ,result,flag_multi);
if(query.indexOf(".fix_icarus_sqa") === 0 ){//如果为上下文添加了类名,就要去类名
for(i = 0; node = contexts[i++];){
if(node.nodeType === 1){
node.className = node.className.replace(" fix_icarus_sqa","");
}
}
}
return result;
}catch(e){}
}
}
但显然对类进行操作对调用dom.contains快捷得多了。
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
浙公网安备 33010602011771号