Ruby's Louvre

每天学习一点点算法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

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快捷得多了。

如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码

posted on   司徒正美  阅读(2701)  评论(1编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2010-11-08 javascript 测试工具 abut v2
2010-11-08 检测浏览器使用什么语言
2009-11-08 字符串的乘法
点击右上角即可分享
微信分享提示