欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

升级你的CSS技能:原生JS的getComputedStyle和设置样式的方法详解

最编程 2024-01-19 13:27:14
...

说了这么多,接下来将用原生 JS 实现一个小组件,实现 CSS 的 get 与 set,兼容所有浏览器。

完整的组件代码在我的 github 上,戳我直接看代码

getStyle(elem, style)

对于 CSS 的 set ,对于支持 window.getComputedStyle 的浏览器而言十分简单,只需要直接调用。

1
2
3
4
5
6
getStyle:  function (elem, style) {
     // 主流浏览器
     if  (win.getComputedStyle) {
         return  win.getComputedStyle(elem,  null ).getPropertyValue(style);
     }
}

反之,如果是 IE 浏览器,则有一些坑。

opacity 透明度的设定

在早期的 IE 中要设置透明度的话,有两个方法:

  1. alpha(opacity=0.5)
  2. filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc’, endColorstr = ‘#ddddd’ );

因此在 IE 环境下,我们需要针对透明度做一些处理。先写一个 IE 下获取透明度的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// IE 下获取透明度   
function  getIEOpacity(elem) {
     var  filter =  null ;
 
     // 早期的 IE 中要设置透明度有两个方法:
     // 1、alpha(opacity=0)
     // 2、filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc’, endColorstr = ‘#ddddd’ );
     // 利用正则匹配
     filter = elem.style.filter.match(/progid:DXImageTransform.Microsoft.Alpha\(.?opacity=(.*).?\)/i) || elem.style.filter.match(/alpha\(opacity=(.*)\)/i);
 
     if  (filter) {
         var  value = parseFloat(filter);
         if  (!isNaN(value)) {
             // 转化为标准结果
             return  value ? value / 100 : 0;
         }
     }
     // 透明度的值默认返回 1
     return  1;
}

float 样式的获取

float 属性是比较重要的一个属性,但是由于 float 是 ECMAScript 的一个保留字。(ECMAScript保留字有哪些?戳这里

所以在各浏览器中都会有代替的写法,比如说在标准浏览器中为 cssFloat,而在 IE678 中为 styleFloat 。经测试,在标准浏览器中直接使用 getPropertyValue("float") 也可以获取到 float 的值。而 IE678 则不行,所以针对 float ,也需要一个 HACK。

width | height 样式的获取

然后是元素的高宽,对于一个没有设定高宽的元素而言,在 IE678 下使用 getPropertyValue("width|height") 得到的是 auto 。而标准浏览器会直接返回它的 px 值,当然我们希望在 IE 下也返回 px 值。

这里的 HACK 方法是使用 element.getBoundingClientRect() 方法。

element.getBoundingClientRect() -- 可以获得元素四个点相对于文档视图左上角的值 top、left、bottom、right ,通过计算就可以容易地获得准确的元素大小。

获取样式的驼峰表示法

上文已经提及了,在IE下使用 currentStyle 要获得属性名的话必须采用驼峰式的写法。

OK,需要 HACK 的点已经提完了。那么在 IE 下,获取样式的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
getStyle:  function (elem, style) {
     // 主流浏览器
     if  (win.getComputedStyle) {
         ...
     // 不支持 getComputedStyle
     else  {
         // IE 下获取透明度
         if  (style ==  "opacity" ) {
             getIEOpacity(elem);
         // IE687 下获取浮动使用 styleFloat
         else  if  (style ==  "float" ) {
             return  elem.currentStyle.getAttribute( "styleFloat" );
                 // 取高宽使用 getBoundingClientRect
         else  if  ((style ==  "width"  || style ==  "height" ) && (elem.currentStyle[style] ==  "auto" )) {
             var  clientRect = elem.getBoundingClientRect();
 
             return  (style ==  "width"  ? clientRect.right - clientRect.left : clientRect.bottom - clientRect.top) +  "px" ;
         }
         // 其他样式,无需特殊处理
         return  elem.currentStyle.getAttribute(camelize(style));
     }
}

setStyle(elem, style, value)

说完 get ,再说说 setStyle ,相较于getStyle ,setStyle 则便捷很多,因为不管是标准浏览器还是 IE ,都可以使用 element.style.cssText 对元素进行样式的设置。

cssText -- 一种设置 CSS 样式的方法,但是它是一个销毁原样式并重建的过程,这种销毁和重建,会增加浏览器的开销。而且在 IE 中,如果 cssText(假如不为空),最后一个分号会被删掉,所以我们需要在其中添加的属性前加上一个 ”;”  。

只是在 IE 下的 opacity 需要额外的进行处理。明了易懂,直接贴代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 设置样式
setStyle:  function (elem, style, value) {
     // 如果是设置 opacity ,需要特殊处理
     if  (style ==  "opacity" ) {
         //IE7 bug:filter 滤镜要求 hasLayout=true 方可执行(否则没有效果)
         if  (!elem.currentStyle || !elem.currentStyle.hasLayout) {
             // 设置 hasLayout=true 的一种方法
             elem.style.zoom = 1;
         }
         // IE678 设置透明度叫 filter ,不是 opacity
         style =  "filter" ;
 
         // !!转换为 boolean 类型进行判断
         if  (!!window.XDomainRequest) {
             value =  "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity="  + value * 100 +  ")" ;
         else  {
             value =  "alpha(opacity="  + value * 100 +  ")"
         }
     }
     // 通用方法
     elem.style.cssText +=  ';'  + (style +  ":"  + value);
}

到这里,原生 JS 实现的 getStyle 与 setStyle 就实现了,完整的代码可以戳这里查看。可以看到,一个简单接口的背后,都是有涉及了很多方面东西。虽然浏览器兼容性是一个坑,但是爬坑的过程却是我们沉淀自己的最好时机。

jQuery 这样的框架可以帮助我们走的更快,但是毫无疑问,去弄清底层实现,掌握原生 JS 的写法,可以让我们走得更远。

 

原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

如果本文对你有帮助,请点下推荐,写文章不容易。

最后,本文组件示例的代码贴在 我的github 上。

我在 github 上关于 jQuery 源码的全文注解,感兴趣的可以围观一下。jQuery v1.10.2 源码注解 

 


本文转自ChokCoco博客园博客,原文链接:http://www.cnblogs.com/coco1s/p/5210667.html

推荐阅读