在前边几篇文章中,我们封装了基本的选择器通过$get(selecteor,parent)选取指定元素下的选择器,但是并不完美,作为一个追求完美的前段开发工程师加上与之俱来的强迫症,这些代码功能,怎么能满足呢,下面,我们又要把这些代码进行升级,就像LOL,大家都懂得哦;那么首先我们来分析情况,参数selector会有很多的形式,比如:“div,#header,.content,input
”,或者“div form input” 又或者 "div span,p .content",我们依次给他们起名为:分组选择器,层次选择器,分组加层次选择器.
我们首先分析分组选择器,看到分组选择器的形式,我们是不是特别想把他变成一个数组,因为这样就可以循环遍历每一个出来,然后就可以进行选取,很明显他是一个字符串,这是后我们就要利用js中字符串提供的API,split()方法完美解决了我们的难题,使用切割字符串的发法,返回一个数组,就可以得到自己想要的:
var groups=selector.split(",");//返回一个数组是不是很完美,这个时候我们就可以循环遍历,但是我们不使用for()循环,使用自己封装的,这样的才显得不是很Low,开玩笑了了,使用自己封装的,只是更加法方便,提高性能。这是自己分改装的each方法:
function each(arr,fn){ for (var i = 0, len = arr.length; i < len; i++) { var result=fn.apply(arr[i],[i]); if(result===false){ break; } }; }
参数fn是回调函数,apply方法我们改变了this的指向,我们将得到的每一项原始数据调用$get(selector,parent)方法,得到的数组存放进result中,最后返回。代码参考:
function $group(selector,parent){ //声明变量,作为返回 var result=[]; if (typeof selector === "string"){ var groups=selector.split(",");//返回一个数组 each(groups,function(){ var singleResult=$get(this.valueOf(),parent);//返回值是数组 result.push.apply(result,singleResult); }); } return result; }至此,我们完成了分组选择器的封装。接下里来,我们分析层次选择器。
层次选择器的形式“#box .content span”,也就是说,我们要寻找的是id是box下的 类名是content 下的 span元素,content是box的下一级,box是content的父级,content是span的父级,我们每次所要查找的元素都是在父级元素下所要查找的结果,简单的举个例子,使用$get()方法找到box后,content的父级元素就是box;代码参考:
function $level(selector,parent){ var singleResult; if (typeof selector === "string"){ var levels=selector.split(" ");//["div","form","select"] each(levels,function(i){ var singleLevel=this.valueOf(); singleResult=$get(singleLevel,singleResult || parent); }) } return singleResult; }还有一点要注意,就是声明singleResult的时候,不能放在each()函数中,以为此时武打记录到值,如果你放到了each函数中,第一次循环,记录了 singleResult的值,第二次循环的时候,就会被重置,这点要注意。
最后我们就要封装分组加层次选择器,封装了前面两个,相信自己已经有了思路,我们只要清楚的分析执行过程,相信他不是难题,这里我们直接贴出代码,作出了注释:
function $groupAndLevel(selector,parent){ var result=[]; if(typeof selector === "string"){ var groups=selector.split(",");//["div form input","p .content"] each(groups,function(){ var singleGroup=this.valueOf();//取得“div form input'” //发现singleGroup是一个层次选择器,直接调用层次选择器方法 var singleGroupResult=$level(singleGroup,parent); if (singleGroupResult){ result.push.apply(result,singleGroupResult); } }); } return result; }; return $groupAndLevel;同样,我们将字符串切割返回数组,案后each循环,发现他是一个层次选择器,我们直接调用层次选择器方法就可以,因为singleGroupResult此时不一定会有值,所以我们使用if判断一下。