jquery选择器扩展之样式选择器

https://github.com/wendux/style-selector-jQuery-plugin

http://blog.csdn.net/duwen90/article/details/50570848

http://www.jianshu.com/p/88c101483a9d

jquery中提供了丰富多样的选择器,利用这些选择器我们可以完成大多数任务,但是喜欢思考的我们总得找点事,提问时间:
1.如何选择所有字体颜色为红色的元素
2.如何选择出背景颜色为为白色的元素
3.如何选择出字体大于等于16px的元素
4.如何选择出背景元素为白色并且文字颜色为黄色的元素
等等等等......总之一句话:如何通过css的样式规则来选择元素?


是不是感觉jquery自带的选择器力不从心了吧,好吧,高手就是喜欢这个时候出手得意,鄙人闭关一个时辰,苦思冥想,悟出了这么一个利器,吾命其名为jquery样式选择器插件,少年,既然你能看到我这篇博客,也是有缘人,就不卖你10块钱了,点个赞拿去吧!从此妈妈再也不用担心老师会问如何根据元素的样式特征去选择元素了,看看引入样式选择器插件后,上面几个问题是怎么简单轻松easy nice 搞定的

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



原理:jquery支持选择器扩展:

$.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这种语义化的写法只是为了给开发人员方便而已。


It's your turn. 少年去尝(碰)试(壁)吧!


-----------------------------------------------------------------------------------------------------
----------我是分割线,如果你实现了,或者已经碰的头破血流了,那么请往下看,看看大师是怎么实现的---------------
------------------------------------------------------------------------------------------------------


可以看到我们的选择器字符串是一个对象{}的串,为什么要这样,这可是很巧(xin)妙(ji)的:原因有两个:

1.解析时可以直接用eval转化成js对象 
2.css样式非常多,我们不可能在解析时逐一对比到底是哪个样式有规则(可能是font-size也可能是color....),因为最终我们是要通过jquery方法的css去匹配,而css方法正好可以接受一个对象。【ps:这一点不能理解的话你可以试着不要看下面源代码想想定义成其它格式怎么实现,然后你就会默然回首,恍然大悟,大赞一声"喵"的】


如何支持运算符, 无非就是== > < >= <= 这几种,一个正则搞定:/^[><=!]?=?/。


颜色问题怎么办? 关键是思维! 我们虽然不知道自己设置的和再去取得的样子是不是一样,比如我们css中写的是red,我们不用css()返回后的结果a(可能是#ff0000)直接和我们选择器字符串中的值b(red)相比,而是我们先把b设置到某个元素E中之后,然后再用css()取出E的color,记为c,最后用c去和a去比较! (好好体会一下)。 


能看到这里,少年,好样的,我果然没有看错你,但是先别高兴,我们还有一个问题,那就是E什么时候创建(当然E肯定是不能显示的,display:none),我们不能每次比较前都创建一个元素吧,对的,缓存!


好了,既然到这一步了,那么代码你也应该能看懂了! 来想象一下,这么狂拽炫酷屌炸天的功能,代码得有多少行? 大胆一点!


看看源码长啥样:

/*
 author:duwen 2015.9.3 
 */
  
+function($){
 $.extend($.expr[':'],
 {
    css: function(e, i, m)
    {
        "use strict";
        var s=eval("("+m[3]+")")
        var r=/^[><=!]?=?/;
        var t,cc
        for(var c in s){
            s[c]=s[c].replace(r,function(w){t=w;return ""})
            if(t=="")t="==";
                if(!m[9]){ 
                  var d=$("#_csss");
                  m[9]=d[0]&&d||$("<div id='_csss' style='display:none'>").appendTo("body") 
                }
                m[9].css(c,s[c]); 
                cc=m[9].css(c);
                if (eval("$(e).css(c)"+t+"cc"));
                else return false;
        }
        return true;
    }   
 });
}(jQuery);

惊艳了吧~

原文地址:https://www.cnblogs.com/daysme/p/8053460.html