DomQuery入门

什么时候应用到DomQuery?DomQuery的作用是什么?不少读者都会对DomQuery感到好奇,在理解DomQuery的作用之前,我们不妨先拿另一体系的技术作参照对比:CSS在Web开发中用于定义外观的样式,我们回顾一下CSS是怎样定住页面上的某个元素,或某组元素、某组标记的,见如下的CSS样式表:

#x-css-browser .x-tree a i {

color:#FF4545;

font-style:normal;

}

通过各种不同的元素搭配使用,来定位某个、某组DOM节点在CSS文件中是相当轻松的事情,同时任意的查询组合也是相当灵活的,但把同等概念放到脚本文件中可不是一件轻松的事情,原因在于读取CSS格式文件然后解析的整个过程是浏览器引擎内部处理的,脚本中的实现只是属于脚本引擎级别的处理,也就是说需要通过这个脚本引擎运算过,然后才得到目标的节点。DomQuery,顾名思义是参照了CSS定位元素的思路设计的查询类,实现以一种简便的方法迅速定位页面中的某一节点。其应用场合较常见于没法使用id标记获取方式的情况下,以便更精确地定位某个元素,或某个集合的元素。
1.XPath能否胜任需求

面对这种需求,我们首先想到的解决方案可能是XPath技术。为什么不用XPath呢?XPath支持绝对定位,例如//input[@id=‘3’];也支持相对定位,例如./input[0],甚至支持根据节点内容定位, 例如//a[contains(., ‘partial text’)]。可以说XPath的功能全面且强大,但是在实际使用中, 我们却发现XPath并不是那么方便。

关键的问题是,在一个复杂的界面控件中,HTML节点本身的结构与界面展现结构并不是一致的,例如一个特定效果的边框可能需要多个HTML元素互相嵌套才能够实现, 因此XPath的相对路径选择能力往往派不上用场,而根据内容定位的方式则过于灵活,难以维护一个稳定的概念层。相比较而言,CSS的选择符所提供的节点定位方式要比XPath更加简单直观,它的适用性也早已在大量的实践中得到了证实。基于CSS选择符实现的查询机制是一种更加可行的方案。
2.DomQuery的实力

DomQuery 在Ext中以单例(Singleton)的形式出现。简而述之,DomQuery的作用就是通过CSS选择符(CSS Selector)选取目标节点元素,若找不到目标节点就返回null值。例子中的CSS转为JavaScript脚本的CSS选择符,将会是:

*[id=x-css-browser]/*[class=x-tree]/A/I

在 Ext的名字还是称为YUI-Ext的早期版本中,当时没有CSS Query库,负责此功能的是来自Dean Edweads的CSS Query库。先前提及要在脚本中实现CSS风格的查询实际涉及大量的循环运算,运行在脚本引擎中,而且构成组件UI、对组件绑定事件的操作都将频繁使用到CSS查询,所以查询的速度对整个库的效率有着密切的影响,查询成绩也是各个JavaScript库之间、脚本引擎之间速度上的分水岭。



在通常情况下,我们可以通过Ext.get/fly的方法获取页面上某个元素,但若我们想获得多个页面上的元素,相应的做法是怎么样的呢?答案就在于DomQuery类中的select/query方法。由于使用频率较高,我们将这两个方法挂到Ext的这个命名空间下,省去每次 Ext.DomQuery.select()/Ext.DomQuery.query()冗长的调用方式。

DomQuery的select方法有两个参数:

* 第一个可以是选择符字符(Selector String),即当前我们所说的“CSS选择符”。

* 第二个是欲生成查询的标记ID(Tag ID)。
3.5.1 元素选择符Selector

DomQuery 提供大多数的CSS3选择符,同时也支持基本的XPath以及自定义两种格式的选择符。我们以一个普通的HTML文档为基础,假设想获取文档内所有的 “span”标记:

/*供测试的HTML清单在光盘\第03章 Ext基础\DomQuery入门 CSS值元素选择符.htm*/

Ext.query("span"); //这个查询会返回有两个元素的数组,因为查询选中了对文档的所有span

//这个查询会返回有一个元素的数组,因为查询顾及到了foo这个id

Ext.query("span", "foo");

注意刚才怎么传入一个普通的字符串作为第一个参数。按id获取标记,你需要加上“#”的前缀:

Ext.query("#foo"); //这个查询会返回包含foo div一个元素的数组

按属性class的名称获取标记,你需要加上“.”的前缀:

/*

这个查询会返回有一个元素的数组,包含与先前例子一样的div,但是我们使用了class name来获取

*/

Ext.query(".foo");

你也可以使用关键字“*”来获取所有的元素:

Ext.query("*"); //这会返回一个数组,包含文档内的所有元素

要获取子标记,我们只需在两个选择符之间插入一个空格:

Ext.query("div p"); //这会返回有一个元素的数组,内容为div标记下的p标记

Ext.query("div span"); //这会返回有两个元素的数组,内容为div标记下的span标记
3.5.2 属性选择符Attributes Selectors

这些选择符可让你得到基于一些属性值的元素。属性指的是HTML元素中的href、id或class。例如:

/*供测试的HTML清单在光盘\第03章 Ext基础\DomQuery入门 属性选择符.htm*/

//现在我们针对特定的class属性进行搜索

Ext.query("*[class=bar]"); //这会得到class等于“bar”的所有元素

Ext.query("*[class!=bar]"); //这会得到class不等于“bar”的所有元素

Ext.query("*[class^=b]"); //这会得到class从“b”字开始的所有元素

Ext.query("*[class$=r]"); //这会得到class由“r”结尾的所有元素

Ext.query("*[class*=a]"); //这会得到在class中抽出“a”字符的所有元素

//检查出任何存在有class属性的元素。这个查询会返回4个元素的数组

Ext.query("*[class]"); // 结果:[div#bar.foo, span.bar, div#foo.bar, span.bar]

截图如图 3.2所示。

图3.2 用Firebug观察返回的结果
3.5.3 CSS值元素选择符

可以通过编写脚本代码来实时控制页面的CSS样式,这些控制所产生的修改结果会即时同步反映在页面上——这便让我们“修改皮肤/主题”的时候可以立刻看到修改的效果。

同样,也可以访问这些DOM元素的style属性,查询每一个元素拥有哪些属性和属性的值,也就是遍历当前的样式效果——它们都一一地记录在客户端的内存中。基于这种CSS值的查询就是所谓的“CSS值元素选择符”,CSS的设置就变为一种查询的条件。这些选择符会匹配DOM元素的style属性。

首先我们为前面例子中的HTML加上一些颜色,即加入CSS样式。基于这个CSS的颜色值我们不会做任何查询,但可以是其他的内容。它的格式规定是这样的:

元素{属性 操作符 值}



/*供测试的HTML清单在光盘\第03章 Ext基础\DomQuery入门 CSS值元素选择符.htm*/

Ext.query("*{color=red}"); //获取所有红色的元素[div#bar.foo]

// 获取所有粉红颜色的并且是有红色子元素的元素

Ext.query("*{color=red} *{color=pink}"); // [span.bar]

// 获取所有不是红色文字的元素

Ext.query("*{color!=red}");

// [html, head, script firebug.js, link, body#ext-gen2.ext-gecko, script

// ext-base.js, script ext-core.js, span.bar, a www.extjs.com, div#foo.bar,

// p, span.bar, a test.html#]

// 获取所有颜色属性是从“yel”开始的元素

Ext.query("*{color^=yel}"); // [a www.extjs.com]

// 获取所有颜色属性是以“ow”结束的元素

Ext.query("*{color$=ow}"); // [a www.extjs.com]

// 获取所有颜色属性包含“ow”字符的元素

Ext.query("*{color*=ow}"); // [a www.extjs.com, span.bar]
3.5.4 Ext.query与Ext.select的使用注意事项

Ext.query 和Ext.select的作用是一致的,同是根据CSS选择符查找出一个或多个元素。区别在于返回类型上。分别是:query方法返回的是 JavaScript标准的数组类型;select方法返回的是CompositeElement类型,试比较:

alter(Ext.isArray(this.query('a.BigClass'))); //true

alter(this.query('a.BigClass').length);

this.select('a.BigClass').each(function(i){

i.dom.href = 'javescript:void(0);'// 找到所有带有BigClass样式的A元素修改其链接

});

CompositeElement 类型属于Ext自定义的类型,简单地说是以一个Ext.Element实例代表集合中多个元素,可实现Element对象上所有的接口,也就是说 CompositeElement在Ext中用于表示元素的集合中不论有多少个元素,均被视为一个单独元素处理。

它的用法和单个的Element对象没有不同。select方法返回的结果可直接如同Element般地操作,一般比query方法常用。
3.5.5 元素ID/Class知识拾遗

W3C组织定义的HTML格式的文档里,id(Identifier)为“元素独一无二的标识”。即合理的情况下,一份良好的HTML文档中没有两个id命名是相同的,可利用id属性值获取此元素,或根据此id在CSS中定义外观。

Class 属性也可以与CSS样式表定义相呼应,设定样式表。实际前端编码中,Class属性与样式表比id属性意义上更来得紧密。它可支持一个到多个的样式名称,用空格分隔开,这样写就可以避免可能出现的冗长的CSS命名,显得更清晰,额外的好处是可重用某些CSS表中常用的定义。

属性 id与元素的关系是“一对一”的,class可将具有某些特征的元素归为一类,其关系可体现为“多对一”(多个元素对应某种class)。两者组合起来用于查找页面上的某个元素,即CSS选择符(CSS Selector),形成一种查询条件输入,将页面上符合各种条件的元素查找出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值