• 面向对象的CSS--OOCSS


          时下流行面向对象,那么有没有可能把样式表也面向对象一下呢,将现在的CSS(Cascading Style Sheets层叠样式表)进

    化一下,演变成面向对象的样式表给套了个概念上去,以下叫“OOCSS”,即 Object Oriented Cascading Style Sheets。

     

     ◆ 为什么会这样想?

          没办法,被逼的, 俺们公司的美工只做图片,其它的是啥都不管,近来弄个WEB项目,都做差不多了,老总说要能换肤。呵呵

    还好之前有所考虑,三两天就搞定了。

          我的方法是,页面全部用CSS控制,主要有 common.css、list.css、addedit.css等10来个css文件和图片,全部放一个叫

    Common/Skins的目录下 ,Common/Skins下每套皮肤一个文件夹,最终目录结构大致如下。

    Code

          共定义有5、6套皮肤,CSS和图片文件急剧上涨,由原来的10来个一下子上升到了7,8十个,虽然数量是有点吓人,不过每套

    皮肤,CSS和图片都大部分差不多,也没花多少功夫就搞定了,不管了,甩一边。

          几天后的某一天早晨,好大的台风,呼呼的,雨也不小,让人觉得很不爽,就像出事前的预兆 !

          果然,没坐下多久,老总过来说“和美工讨论了下,有几个地方,布局要变下......”。

          一阵的嘻哩哗啦之后,我心里除了佩服老总口才不错之外,觉得自己命好苦呀!

          那么多CSS,得改多久呀,以后要再变的话不还得改吗!

          仔细分析下CSS,其实每套皮肤都大体差不多,不同的地方一般都是边框、文字的颜色和背景色,还有图片、字号,于是我决定

    所有的皮肤都用同一套公共的CSS文件,另外,每套皮肤再加一个独立CSS文件(Settings.css),而该CSS中只定义基本的样式,

    相当于配置文件一样的,然后作用于其余几个公共的CSS文件。

          我坚信这样的思路是对的,可是怎么实现呢?

          首先想到的,当然是用CSS的组合,将之前部分CSS规则分离,公共部分提取出来放在 Settings.css中定义,如:

          将List.css中规则 
                   .ToolBar{color:#f0e000;border:1px solid gray;} 
              分离为
                   .DefaultColor{color:#f0e000;}定义在Settings.css中
                   .ToolBar{border:1px solid gray;}仍然保留在List.css中

              然后将HTML中对 .ToolBar 的引用“class='ToolBar'”改为“class='DefaultColor ToolBar '”

          再将其它color属性相同的CSS规则进行同样的分离。这样每套皮肤不同的地方就只是 settings.css文件里.DefaultColor类型

    的规则。

          而这样做又引发的新的问题,必须得每个页面改HTML中的class属性,而背景图片只能依靠 expression 来解决,expression

    又常常造成页面的死锁,无奈之下只有另谋出路。

          

     ◆ 面向对象的CSS: OOCSS 基本构思

          继承:

                OOCSS中,类(样式规则)可以继承自另一类,如

    例一

                .Base{font-size:20pt;}
                .Sun{color:red;}

                假如用如下语法可以实现继承

                .Base{font-size:20pt;}
                .Sun (inherit .Base)
                {
                        color:red;
                }

                而现在类 .Sun 则不单单拥有 “color:red;”属性,应该拥有从基类 .Base 中继承的 “font-size:20pt”属性 ,

         cssText应该是 “font-size:20pt;color:red”。

          覆盖:

               将上例中的 .Sun 更改如下:

                .Base{font-size:20pt;}
                .Sun (inherit .Base)
                {
                        font-size:10pt;
                        color:red;
                }

                则实现了对基类“font-size:20pt”的覆盖,.Sun中的font-size则为10pt。

         子类访问基类

    例二

                .Base
                {
                        v:20;
                        font-size:20pt;
                }


                .Sun (inherit .Base)
                {
                        padding : (base.v+10)px;
                        font-size:(base.fontSize/2)pt;
                        color:red;
                }

                .Sun2 (inherit .Base)
                {
                        padding : (base.v+20)px;

                }

               在基类 .Base 中定义了变量 “v:20”和style属性“font-size:20pt”,子类 .Sun和.Sun2中style属性padding和

         font-size通过访问基类变量和属性计算而来,而最终 .Sun 中 padding等于30px,.Sun2中padding等于40px;.Sun中

         fong-size等于10pt,.Sun2没有覆盖基类中的font-size,所以font-size继承基类,值仍为20pt。

         多继承

    例三

                .Base{font-size:20pt;}

                .Base2{color:red;}

                .Sun (inherit .Base,.Base2)
                {
                        padding:20px;
                }

                .Grandson (inherit .Base)
                {

                }

     


              类.Sun继承自两个基类.Base和.Base2,所以.Sun的cssText为“font-size:20pt;color:red;padding:20px;”,而

         .Grandson继承自.Sun,本身没有任何自定义属性,因此cssText和.Sun一样,仍为“font-size:20pt;color:red;

         padding:20px;”。

          

         私有(假如用private作为关键字)

    例四
                .Base
                 {
                        font-size:20pt;
                        private color:red;
                 }

                .Sun (inherit .Base)
                {
                        padding:10px;
                }

              子类 .Sun 继承基类 .Base 中的fontSize属性,因为 .Base中color属性受private(私有)限制,不能被.Sun继承,最终

         .Sun的cssText是“font-size:20pt;padding:10px”。

         更多特性待琢磨......

     

     

      ◆ 这样做有意义吗?

           我的回答是“有”     !

           1.  CSS的优点之一“一处定义,多处使用”

                   目前的CSS多处使用指的是,一个CSS规则可以由多个HTML元素引用。可CSS规则间不能互操作。

           2.  CSS的继承

                   CSS的继承不是真正意义上的继承,而是HTML元素对外层元素Style属性的继承,且部分Style属性、HTML元素是不能

              继承的,如backgroundColor属性、border属性、padding属性、table元素等等(当然,部分不支持继承也是合理的)。

          3.  CSS优先级

                   当多个CSS规则作用于同一个HTML元素时,CSS将根据CSS规则权重 、规则定义的先后配合HTML元素的层次关系决

              定最终的有效值,这样的解决方案有时很巧妙,可当HTML层次结构过深、而作用于同一个HTML元素的CSS规则过多时,

              CSS规则的优先级控制是相当的不容易,有时候不得不用蹩脚的“! important”来解决问题,可“! important”不符合标

              准,支持的浏览器很少。

          OOCSS在保留CSS特性(或者说是优点)的前提下,将从某种程度上解决以上问题

         1.  OOCSS中,类可以访问基类甚至没有依赖关系的其他类,应用灵活......。

         2.  OOCSS中,继承是类对基类属性的继承,不同于CSS中的继承(HTML元素对上层元素Style属性的继承),子类直接继承

              基类不受private(私有)关键字修饰的属性。

         3.  OOCSS实现继承后,就会在一定程度上避免CSS组合的应用,便会减少意外的HTML元素匹配,同时HTML元素在class属

              性中应用子类时,权重跟基类无关,和子类一致,如例三中,子类 .Sun 的权重跟基类 .Base1、.Base2无关 。

     

     ◆ 我认为OOCSS很有趣,也有用,那么该怎么做呢?

               上面的想法都是建立在假如的基础上的,都只是我一种猜想而已

                .Base
                 {
                        font-size:20pt;
                        private color:red;
                 }

                .Sun (inherit .Base)
                {
                        padding:10px;
                }

                这样的代码各位都不认识,浏览器又怎么会认识呢,那么是不是就不能实现呢?不是的,我们可以通过一些其他方法模拟,

           虽然有些尴尬!

                我的做法是,写个JS解析,基本实现以上想法,代码太多,不方便贴出来,供下截

                     下载:http://www.66s.com.cn/oocss/OOCSSDemo.rar
                             https://files.cnblogs.com/kuiyouli/OOCSSDemo.rar

                     演示:http://www.66s.com.cn/oocss/

                     有兴趣的朋友可进入QQ群:15774494

                     注:目前只支持IE浏览器

           实现功能如下:

           1.  继承 

                    因为浏览器不支持 .Sun (inherit .Base) 这样的语法,所以改为如下形式:

                        .DefaultColor{color:red;}
                        .Sun
                        {
                             base: .DefaultColor;
                             font-size:9pt;
                        }
                    用 “base”关键字指定基类,注意是“.DefaultColor”,而不是“DefaultColor”,基类必须是类全称,可以指定多个基

              类,如:

                        .BaseHeight{height:30px;}
                        .DefaultColor{color:red;}
                        .Sun
                        {
                             base: .DefaultColor,.BaseHeight;
                             font-size:9pt;
                        }          

           2.  附加

                    跟继承类似,实现的却是CSS的组合功能。

                        .BaseHeight{height:30px;}
                        .DefaultColor{color:red;}
                        .Sun
                        {
                             append: .DefaultColor,.BaseHeight;
                             font-size:9pt;
                        } 

                   当HTML元素引用类 .Sun 时,OOCSS会自动将 .DefaultColor、.BaseHeight附加到HTML元素的class属性,如:

                        <div class=".Sun"></div>

                   则该div最后的class属性值为“.Sun .DefaultColor .BaseHeight”。因此,.DefaultColor、.BaseHeight中的属性受

              其优先级的影响,跟.Sun的优先级无关。

          3.   eval表达式

                   eval表达式类似expression表达式,不同之处在于,eval只在初始化时执行一次。

                         .TestEval
                        {
                             E-height: eval(20+30);
                        }

                   相当于:

                         .TestEval
                        {
                             height: 50px;
                        }

                   可以在eval中访问脚本变量,如:

                        <script>
                             var skin={color:'red', defaultSize:'9pt'}
                        </script>

                        <style>
                             .TestEval
                             {
                                  E-color: eval(skin.color);
                                  E-font-size: eval(skin.defaultSize);
                             } 

                             .LargeFont
                             {
                                  e-font-size:eval(     (parseInt(skin.defaultSize)+3)+"pt"     )
                             }
                        </style>

                   以上代码相当于:

                        <style>
                             .TestEval
                             {
                                  color: red;
                                  font-size: 9pt;
                             }
     

                             .LargeFont
                             {
                                  font-size:12pt;
                             }
                        </style>                    

         4.  .Global或.Init初始化

              可以类名为 .Global或 .Init的类配合eval关键字初始化。

                       <style>

                             .Global
                             {
                                  E-init: eval(     window.skin={color:'red', defaultSize:'9pt'}     );
                             }


                             .TestEval
                             {
                                  E-color: eval(skin.color);
                                  E-font-size: eval(skin.defaultSize);
                             }
                        </style>

                   以上代码相当于:

                        <style>
                             .TestEval
                             {
                                  color: red;
                                  font-size: 9pt;
                             }
                        </style> 

         5.  访问基类

              通过eval关键字和base关键字,访问基类对象。

                        .DefaultHeight{height:30px;}
                        .Sun
                        {
                             base: .DefaultHeight;
                             E-height: eval(parseInt(base.height)+20);
                        }

               相当于:

                        .Sun
                        {
                             height: 50px;
                        }

               当有多个基类时,则可以这样访问:

                        .DefaultColor{color:red;}                    
                        .DefaultHeight{height:30px;}
                        .Sun
                        {
                             base: .DefaultColor ,.DefaultHeight;
                             E-height: eval(parseInt(base[1].height)+20);
                        }

               也可以这样访问

                        .DefaultColor{color:red;}                    
                        .DefaultHeight{height:30px;}
                        .Sun
                        {
                             base: .DefaultColor ,.DefaultHeight;
                             E-height: eval(parseInt(base[DefaultHeight].height)+20);
                        }

               相当于:

                        .Sun
                        {
                             color: red;
                             height: 50px;
                        }

      

         6.  私有成员

              下一版本实现......

    TrackBack:http://www.cnblogs.com/kuiyouli/archive/2008/10/14/1295572.html

  • 相关阅读:
    java+根据多个url批量下载文件
    js拖拽文件夹上传
    php文件夹上传
    java上传大文件解决方案
    web文件系统
    WebService之CXF注解之三(Service接口实现类)
    oracle 推断字符是否为字母
    二分查找算法
    C# 杀掉后台进程
    (个人开源)ffpanel --ffmpeg的GUI,让ffmpeg离开黑黑的命令行
  • 原文地址:https://www.cnblogs.com/hdjjun/p/1311532.html
Copyright © 2020-2023  润新知