强大的 jQuery 自定义选择器: css

1,407 阅读5分钟
原文链接: www.jianshu.com

jQuery中提供了丰富多样的选择器,利用这些选择器我们可以完成大多数任务,我们现在来思考如下几个问题:
1.选取字体颜色为红色的所有元素
2.选出背景颜色为白色的元素
3.选择出字体大于等于16px的元素
4.选择出背景为白色并且文字颜色为黄色的元素
5.选出所有字体为红色的元素的字体为14像素的所有子元素
......
总之一句话:如何通过css的样式规则来选择元素?是不是感觉jQuery自带的选择器力不从心了吧,好吧,高手就是喜欢这个时候出手得意,鄙人闭关一个时辰,苦思冥想,悟出了这么一个利器,吾命其名曰jQuery样式选择器。少年,既然你能看到我这篇博客,也是有缘人,就不卖你10块钱了,点个赞拿去吧!看看引入样式选择器插件后,上面几个问题是怎么搞定的

1. $("#c :css({color:'red'})")
2. $("#c :css({backgroundColor:'white'})");
3. $("#c :css({fontSize:'>=16px'})");
4. $("#c :css({backgroundColor:'white',color:'yellow'})");
5. $("#c :css({color:'red'}) :css({fontSize:'14px'})")

原理

jQuery支持扩展选择器,如:first、:last都属于扩展选择器,我们可以定义自己的扩展选择器,如上所见,我定义的选择器就是:css,下面我们来看看如何定义:

$.extend($.expr[':'],{
  selectorName:function(e,i,m){
  //解析自己选择器,其中m是个数组,e是当前元素,m[3]便是选
  //择器字符串,如果返回true代表当前元素被选中,反之则否 
  }
}

看到这里你是不是觉得自己也能实现了呢?too young too simple! 当然,我鼓励你去尝试, 站在设计者的角度,注意几个问题:

  1. 如何进行运算符支持?比如问题3中,要选出字体>=16像素的元素,如果是小于呢? 或者是不等于呢?
  2. 如何支持多个条件匹配,比如问题4中,既要求背景颜色是白色,而且字体是黄色,如果我再加上字体小于18像素并且margin-top大于0,并且是定位方式是fixed……
  3. 假如你css代码中写了这么一句:color:red,然后你在判断是否满足条件时用jquery css("color")取出颜色值a,然后看a和选择器中的色值是否满足条件;这样有问题吗?有! 因为不同浏览器css("color")返回的值是不一样的,如果返回的是"red"那万事大吉,但是返回的可能是#ff0000(这也是红色,只不过换了一个16进制的马甲),这怎么整?好好想想吧!不过你应该知道,浏览器这样做是可以理解的,因为浏览器内部认得肯定是一个数值,而red这种语义化的写法只是为了给开发人员方便而已。

考虑到如上几个问题,便自然而然的产生了一个最麻烦的新问题:如何设计接口?
我们提供的接口要支持关系判断(>,<,>=,<=,!=)和条件逻辑(&&)。当然,如果太复杂就不应该用选择器了,直接写个函数去处理,总不能在选择器里支持js表达式吧。即如此,我们必须找一种优雅的解决方案,该怎么做?既然不能用js复杂表达式, 那能有其它什么东西本身语法表现力可以胜任我们当下的需求,并且能够和js很好的结合(这有助于减少我们的代码量),总不能引入一个库来解析表达式吧。想到这里,想必大家心里自然有了答案,对,就是json.="" 当然,正如上面所示,最终的接口竟是如此优雅,唉,太完美。<="" p="">

想到这里,一个大问题算是解决了,当还有另一个棘手的问题没有结局,那就是上面提出的第三个问题。 本来我想直接告诉你,但本文定位不会太深入,同时也留给你想象的空间,思考过,然后再去看源码,我想我们才会发生真正意义上的互动与交流,毕竟,本人剑道已成多年,到如今,很久未遇对手,寂寞啊 。
在贴出源码之前,我想请大家猜一下这个插件代码量,不用告诉我,自己去看。

源码地址:github.com/wendux/styl…

还是那句老话:欢迎star! 欢迎点赞(请在简书原文哦)!打赏再怎么欢迎,你也不会,以后就不说了。 还有,欢迎访问我的github主页,也许你会发现更多有价值的东西。当然,这都是笨办法了,聪明的孩子都选择了直接关注我。

注:客观来讲,本插件为当年笔者研究jQuery源码时,闲来无事,找乐子的实验性产物,笔者认为实际工程中的有需求的场景不会多,了解我的人应该都知道我比较懒,很少有耐心写博客,不过,这个插件,我曾经在csdn上介绍过一次,jQuery社区插件很多,但关于自定义选择器的却很少见,此次,旧文重写,一来是由于最近粉丝多了,二来也是为了探发幽微。

再注:由于之前几篇文章都是关于前端的,有些人误以为我现在是做前端的,首先谢关心,不过呢,还真不是。之所以开博的几篇文章写前端,我之前的想法是前端程序员多些,吸粉应该比较快。不过你不要害怕,不会把你带到沟里,笔者虽然很谦虚,但也愿意承认一个事实,前端技术虽然广杂,但笔者有信心,在国内的前端的江湖,笔者眼里的没几个人,尤雨溪不错,阮一峰老师在科普上做的工作也值得肯定。也许还有其它一些人可能像我一样,平时太懒不怎么宣传自己所以也不为人知,不过呀,我最近思想发生了变化,所以就开了博客,懒病慢慢治,既然要出世,就先高调一点,毕竟我才发现懒人吸粉不容易啊。

ps:所有互动请在简书原文哦,简书我会经常看,评论也会第一时间回复,掘金到现在我还不怎么会用,之前几篇文章更新后想在掘金同步,愣是没成功,帮助文档也没找到,真是的,放弃了。