`

ExtJs源码分析与学习—ExtJs元素Element(五)

阅读更多

元素的查询Ext.DomQuery

 

    该类结合css选择器可以提供高效的查询。首先说一下DOM中对文档元素的查询,主要有以下方法

  •     document.getElementById(id)
  •     element.getElementsByTagName(tagName)

    DOM对应的6个属性来获取其父、子及兄弟节点的引用

  •     parentNode 指向其父节点的引用
  •     previousSibling 指向前一个兄弟节点的引用
  •     nextSibling 指向后一个兄弟节点的引用
  •     firstChild 指向其第一个节点的引用
  •     lastChild 指向其最后一个节点的引用
  •     childNodes 返回所有子节点的引用的集合


     下面看该类中几个主要方法。先看combination过滤器的实现,共有四种模式,分别为EF,E/F(E>F),E+F,E~F,格模式详见程序中的注释和实现。

 

        /**
	 * 实现combination选择器的查询方式
	 * @param {} ns 要查询的元素或元素集合
	 * @param {} mode 查询模式
	 * @param {} tagName 标签名
	 */
function getNodes(ns, mode, tagName){
        var result = [], ri = -1, cs;
        if(!ns){
            return result;
        }
        tagName = tagName || "*";//没有指定tagName,默认为所有的元素,注意这里用*来查询所有
        //ns参数值为element时,先封装成数组,后续统一处理
        if(typeof ns.getElementsByTagName != "undefined"){
            ns = [ns];
        }
        if(!mode){//后代选择器,符号值为 " " E F模式,查询E标签下所有标签名为F的后代元素
            for(var i = 0, ni; ni = ns[i]; i++){//找到结果集中所有满足的元素
                cs = ni.getElementsByTagName(tagName);
                for(var j = 0, ci; ci = cs[j]; j++){//找到所有满足tagName的后代元素
                    result[++ri] = ci;
                }
            }
        } else if(mode == "/" || mode == ">"){// E/F 或E>F 模式,查询E标签下所有标签名为F的子元素,只有一层,而EF模式为所有后代元素,会有好几层的查询
            var utag = tagName.toUpperCase();
            for(var i = 0, ni, cn; ni = ns[i]; i++){
                cn = ni.childNodes;
                for(var j = 0, cj; cj = cn[j]; j++){
                    if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){
                        result[++ri] = cj;
                    }
                }
            }
        }else if(mode == "+"){// E+F模式,在E标签下的所有元素集合中,查找每个元素的相邻的后续兄弟元素(只找第一个后续兄弟)中标签为F的元素
            var utag = tagName.toUpperCase();
            for(var i = 0, n; n = ns[i]; i++){
                while((n = n.nextSibling) && n.nodeType != 1);
                if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
                    result[++ri] = n;
                }
            }
        }else if(mode == "~"){// E~F模式,在E标签下的所有元素集合中,查找每个元素的相邻的后续兄弟元素中标签为F的元素
            var utag = tagName.toUpperCase();
            for(var i = 0, n; n = ns[i]; i++){
                while((n = n.nextSibling)){
                    if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
                        result[++ri] = n;
                    }
                }
            }
        }
        return result;
    }

 

      接下来看过滤器的实现。Ext.DomQuery中提供了5中过滤方式:id、class、tagName、attribute、pseudo(伪操作根据函数),为此也相应的提供了byId、byClassName、byTag、byAttribute、byPseudo 5个函数来实现,下面主要看byAttribute

 

        /**
	 * 
	 * @param {} cs 要查询的元素结合
	 * @param {} attr 属性名
	 * @param {} value 属性对应的值
	 * @param {} op 操作符
	 * @param {} custom 对于元素属性,采用[],对于css样式则采用{}
	 */
    function byAttribute(cs, attr, value, op, custom){
        var result = [], 
            ri = -1, 
            useGetStyle = custom == "{",	    
            fn = Ext.DomQuery.operators[op],//DOM操作符    
            a,//根据判断的属性来取得元素对应的属性值或css样式属性值
            xml,
            hasXml;
            
        for(var i = 0, ci; ci = cs[i]; i++){
	    // skip non-element nodes.
            if(ci.nodeType != 1){//忽略不是元素节点
                continue;
            }
            // only need to do this for the first node
            if(!hasXml){
                xml = Ext.DomQuery.isXml(ci);
                hasXml = true;
            }
	    
            // we only need to change the property names if we're dealing with html nodes, not XML
            // html节点的处理
            if(!xml){
                if(useGetStyle){
                    a = Ext.DomQuery.getStyle(ci, attr);
                } else if (attr == "class" || attr == "className"){
                    a = ci.className;
                } else if (attr == "for"){
                    a = ci.htmlFor;
                } else if (attr == "href"){
		    // getAttribute href bug
		    // http://www.glennjones.net/Post/809/getAttributehrefbug.htm
                    a = ci.getAttribute("href", 2);
                } else{
                    a = ci.getAttribute(attr);
                }
            }else{
                a = ci.getAttribute(attr);
            }
            if((fn && fn(a, value)) || (!fn && a)){
                result[++ri] = ci;
            }
        }
        return result;
    }

 

    下面看select方法:选择一组元素

 

             select : document.querySelectorAll ? function(path, root, type) {
			root = root || document;
			if (!Ext.DomQuery.isXml(root)) {
				try {
					var cs = root.querySelectorAll(path);
					return Ext.toArray(cs);
				} catch (ex) {
				}
			}
			return Ext.DomQuery.jsSelect.call(this, path, root, type);
		} : function(path, root, type) {
			return Ext.DomQuery.jsSelect.call(this, path, root, type);
		},

 

      该函数分为两种情况,如果支持document.querySelectorAll,优先调用该方法返回。调用传入的参数path为选择器,root为开始查询的节点,默认为document。该方法的别名为"Ext.query = Ext.DomQuery.select;"。另外该类也是单例模式,代码实现比较复杂,内部用到了缓存机制,代码中有三个缓存变量

 

  var cache = {}, 
      	simpleCache = {}, 
    	valueCache = {},
  • cache缓存了选择器的编译(compile)结果
  • simpleCache缓存了选择器的简单(simple)编译结果
  • valueCache 缓存了选择器查询元素的值
分享到:
评论

相关推荐

    深入剖析ExtJS_2.2实现及应用

    作者采用了"core→element→component"的主线,将整个ExtJS源码结构串联起来,确保读者能逐步深入学习,理解每一层的细节。 "Introduction"章节为初学者提供了入门指导,涵盖了ExtJS的基本概念和安装步骤。"Core...

    深入剖析ExtJS 2.2实现及应用连载(全集) DOC精排版!

    本书还深入探讨了JavaScript技术,特别是针对ExtJS源码分析所需的JS知识点。虽然不完全是针对JavaScript初学者,但对于进阶开发者,它提供了许多其他书籍中未涉及的内容,如正则表达式的解析原理和高效正则编写,...

    ExtJS中文手册.pdf

    - **源码细节**:发布ExtJS源码时会涉及到一些具体的细节问题,如文件结构、依赖关系等。 - **从何入手**:对于初学者来说,可以从简单的示例开始,逐步深入到更复杂的组件和功能。 #### 9. 适配器Adapters与核心...

    ExtJS3.0深入浅出(书)源码

    **二、源码分析** 书中对ExtJS 3.0的源码进行了深入解析,帮助读者理解其内部工作原理。这包括: 1. **核心类库**:讲解了Ext的基础类,如Element、Component、Store、Grid等,这些是构建所有组件的基础。 2. **...

    读Ext之十五(操作批量元素)

    在IT行业中,JavaScript库ExtJS是一个广泛使用的前端框架,它为构建复杂的...因此,深入学习"读Ext之十五(操作批量元素)"这篇博客,并结合`CompositeElementLite.js`的源码分析,将是提升ExtJS开发能力的关键步骤。

    【JavaScript源代码】EXTJS7实现点击拖拉选择文本.docx

    在EXTJS7中,开发人员有时需要允许...通过以上分析,我们可以了解到EXTJS7中实现点击拖拉选择文本的机制,以及如何在组件级别和子元素级别进行配置。开发者可以根据实际需求灵活地调整这些配置,以提供更好的用户体验。

    ext-3.0.0源码

    EXTJS 3.0.0源码的分析可以帮助我们深入理解其工作原理,从而更好地利用这个框架来开发复杂的Web应用。 EXTJS的核心是组件模型,它包括各种可复用的UI组件,如表格、面板、表单、树形视图、菜单等。在EXT 3.0.0中,...

    深入剖析EXT 2.2及应用

    书中的内容结构严谨,以"core"(核心)、"element"(元素)和"component"(组件)这三个关键词为主线,串联起EXTJS的整个源码体系。同时,通过一个网络办公系统的实例,将各个知识点贯穿起来,使读者能够逐步学习并...

    EXTJS经典教程

    - **Element对象**:Ext的核心概念之一,用于操作DOM元素,提供了丰富的API来进行DOM操作,如获取、设置样式、位置等。 - **获取多个DOM的节点**:可以通过CSS选择器获取多个DOM节点,并进行批量操作。 - **响应...

    EXT中文手册,ext开发帮手

    手册通常包括EXT的基本概念、安装和下载步骤、组件的使用方法、事件处理、Ajax通信、源码分析等多个章节。其中,"EXT简介"部分会介绍EXT的基本理念和架构;"下载EXT"则会指导开发者如何获取EXT库并将其引入项目;...

    ext js中文开发手册

    源码分析涉及组件架构、事件处理流程、数据绑定机制等方面,对于定制高级功能和调试问题尤为重要。 **九、程序规划入门** 在使用EXT JS进行项目开发前,合理的规划至关重要。这包括选择合适的布局、定义组件层次、...

    asp.net ext 中文手册

    源码分析可以帮助开发者更好地掌握框架的工作原理,从而更有效地进行调试和优化。源码概述章节通常会介绍EXT的架构设计、关键模块的功能及其实现方式,以及在发布源码时需要注意的细节,如依赖管理、代码结构和最佳...

    EXT-js-中文手册

    - **源码分析**:深入分析EXT的源码结构,帮助开发者理解其内部机制。 - **细节讲解**:特别关注了在发布EXT源码过程中需要注意的细节问题,如兼容性考虑、性能优化等。 #### 10. EXT程序规划入门 - **准备工作**:...

    EXT 中文手册内具实例代码

    - **案例分析**:通过具体的案例分析,帮助开发者深入理解 Ext 的使用方法。 综上所述,《EXT 中文手册》涵盖了 Ext 框架的基础知识、核心概念、高级功能以及实际应用案例,对于想要掌握 Ext 开发的读者来说是一份...

Global site tag (gtag.js) - Google Analytics