在(2)中描述了选择器的基本思路和求值步骤,最关键的步骤在于对子表达式的求值,也就是实现XX.selector函数,下面说说思路:
子表达式就是不带','的CSS合法字符串,形式为"expr1 binOp expr2 binOp expr3",其中binOp是二元运算符,expr是由一元表达式组成的字符串,如:"div > ul li.class",XX.selector的目标就是求出符合子表达式的元素集合。
我们可以将子表达式看成由非二元表达式组通过二元运算符连接起来的表达式,如 "div:last-child > ul li.class"可以分成3个非二元表达式组:"div:last-child","ul","li.class",
先求出第一组非二元表达式的值,接着根据二元运算符和后面的非二元组进行过滤,最后的结果就是符合选择器的元素集合。主要步骤如下:
1、 输入子表达式字符串,如"div:last-child","ul","li.class",
2、 对字符串预处理,除去两端空格,除去二元运算符两边多余的空格,
3、 获得第一项非二元组表达式,上述为:"div:last-child"
4、 将非二元组分解为表达式,上述为"div",":last-child"
5、 求出符合非二元组的元素集合ret
6、将剩余的字符串构造为二元组集合binExpr,即为二元运算符加非二元表达式组,也就是符合语法规则 binExpr = expr1 + op + expr2,因为expr1前面我们已经求过值了,所以现在就是根据op和expr2来过滤掉不符合条件的元素,而expr2可以重复利用第4步骤进行分解存储。
6、遍历二元组集合binExpr,根据运算符和expr2筛选符合条件的元素
7、返回ret
对于第2步骤,定义了一组trim函数来实现,
对第3步骤,我定义了一个XX.getExprGroup函数来实现,
对于第4步骤则定义XX.getUnaryExprObj函数来实现该功能。
根据上述步骤,我们可以构件一个基类Expr,带有最基本的filter和toString方法,toString主要用来调试用,filter用来过滤元素,接着继承该基类的有,一元表达式对象UnaryExpr,属性表达式对象AttExpr,伪类表达式对象PseExpr,二元表达式对象BinExpr, 其中除去BinExpr,其他的Expr都带有一个calculate方法,该方法用于计算符合表达式的元素集合,具体如下图所示:
最基本的Expr包含一个op属性,用来保存相关的运算符,其中unaryExpr还有一个term属性,用来保存标识符,AttExpr和PseExpr本身的标识符就是运算符,所以不需要额外属性了,BinExpr则用expr属性保存其非二元表达式组中对应的表达式对象。
在实际的代码中,我并没有写出Expr的代码,也没体现出各个运算符的继承关系,只是在概念上是这么理解的,主要考虑到,这些类所拥有的属性和方法较少,另一方面也为了效率。
具体代码如下:
/*一元表达式构造函数*/
XX.unaryExpr = function(op, term){
this.op = op;
this.term = term;
}
XX.unaryExpr.prototype.toString = function(){
return this.op + this.term;
};
XX.unaryExpr.prototype.calculate = function(context){
//待实现
};
XX.unaryExpr.prototype.filter = function(ret){
//待实现
};
/*伪类表达式构造函数*/
XX.PseExpr = function(op){
this.op = op;
};
XX.PseExpr.prototype.toString = function(){
return ':' + this.op;
};
XX.PseExpr.prototype.filter = function(){
};
/*属性表达式构造函数*/
XX.AttExpr = function(op){
this.op = op;
};
XX.AttExpr.prototype.toString = function(){
return '[' + this.op + ']';
};
XX.AttExpr.prototype.filter = function(){
};
/*二元表达式构造函数*/
XX.binExpr = function(op, exprstr){
this.op = op;
this.expr = [];
/*存储一元表达式对象*/
var start = exprstr.length - 1,
obj = null;
while(obj = XX.getExprObj(exprstr, start)){
this.expr.push(obj.expr);
start = --obj.index;
}
};
XX.binExpr.prototype.toString = function(){
var op = this.op == ' '? '->' : this.op;
return op + this.expr.toString();
};
XX.binExpr.prototype.filter = function(ret){
};
相关trim函数的实现
/*
*去除字符串左边空白
* */
XX.trimLeft = function(str) {
return str.replace(/^\s+/, '');
};
/*去除字符串右边空白*/
XX.trimRight = function(str) {
for(var i = str.length - 1; i > -1 && /\s/.test(str.charAt(i)); --i)
; //不做任何操作
if(i > -1) {
return str.substr(0, i + 1);
}
return '';
};
/*去除字符串两端空白*/
XX.trim = function(str) {
return XX.trimRight(XX.trimLeft(str));
};
XX.getExprGroup与XX.getUnaryExprObj函数的定义
/*顺序获得一组一元表达式字符串
*参数selector:输入的字符串表达式
* start: 开始位置
* 返回值:表达式组字符串
* */
XX.getExprGroup = function(selector, start){
};
/*
* 获取一个表达式对象
* 参数selector:选择符字符串
* 参数curIndex:开始的搜索的索引位置
* 返回值:无表达式则为null,否则返回一个对象,{expr:表达式对象, index:运算符的位置}
* */
XX.getExprObj = function(selector, curIndex) {
//待实现
};
XX.getUnaryExprObj函数之所以返回一个包含运算符位置的index,主要是对字符串方便进行遍历扫描。挤得差不多了,后面再慢慢实现各个表达式类的方法,以及二元表达式的构造函数存储一元表达式的部分。
分享到:
相关推荐
NULL 博文链接:https://goon.iteye.com/blog/1775421
基于BootStrap简洁美观Cron表达式选择器JS插件,只需要在项目中将JS文件导入和基本的BootStrap控件就可以运行,具体可看里面的demo.html
IPhone对@selector的函数如何传参数
代码实现drawable的selector效果,不用为每个控件写selector样式; 另外,实现圆形图片处理、圆角图片处理功能
开发过程中使用阿里巴巴的iconfont来减小apk大小,这是做的一个Demo,里面可以用来实现selector的状态改变,非常好用的,希望对感兴趣的朋友有帮助。
基于BootStrap简洁美观Cron表达式选择器JS插件,只需要在项目中将JS文件导入和基本的BootStrap控件就可以运行,具体可看里面的demo.html
Selector
Flutter的file_selector插件可以帮助开发者在移动应用中方便地选择文件。 要使用file_selector插件,首先需要将插件的依赖项添加到pubspec.yaml文件中,并运行flutter pub get命令获取插件的最新版本。 在插件使用...
在每个对象上,这个事件处理函数只会被执行一次。其他规则与bind()函数相同。这个事件处理函数会接收到一个事件对象,可以通过它来阻止(浏览器)默认的行为。如果既想取消默认的行为,又想阻止事件起泡,这个事件...
NULL 博文链接:https://hbxflihua.iteye.com/blog/2370891
一个强大的selector注入器,它可以让view自动产生selector状态,免去了你写selector的麻烦。
遍历结果: 0 length prevObject context selector ——————————————————————————– constructor init jquery size toArray —————————————————————————
listview selector 选中时改变item 子控件 图片状态
Class(类类型),Selector(选择器SEL),函数指针(IMP) Class(类类型),Selector(选择器SEL),函数指针(IMP)
Android selector 完整demo
selenium css selector 定位详解
ListView Button ImageView 里应用selector选择器切换图片并保持住
基于Python pyqt5的HTTP测试工具源代码,可使用HTTP GET、POST、PATCH、DELETE方法测试网站,可使用正则表达式、XPATH、CSS selector匹配文本
CSS Selector 生成器
带圆角的selector