HTML5技术

【CSS进阶】原生JS getComputedStyle等方法解析 - ChokCoco(2)

字号+ 作者:H5之家 来源:博客园 2016-02-24 15:00 我要评论( )

在早期的 IE 中要设置透明度的话,有两个方法: alpha(opacity=0.5) filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = #ccccc,endColorstr = #ddddd ); 因此在 IE 环境下,

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

  • alpha(opacity=0.5)
  • filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc’, endColorstr = ‘#ddddd’ );
  • 因此在 IE 环境下,我们需要针对透明度做一些处理。先写一个 IE 下获取透明度的方法:

    // 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 下,获取样式的写法:

    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 需要额外的进行处理。明了易懂,直接贴代码:

    // 设置样式 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 源码注解 。

     

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

      HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

      2017-05-02 11:02

    • HTML5 进阶系列:indexedDB 数据库 - _林鑫

      HTML5 进阶系列:indexedDB 数据库 - _林鑫

      2017-04-27 14:02

    • vue的进阶 标签属性数据绑定和拼接 - kengwfpzu920

      vue的进阶 标签属性数据绑定和拼接 - kengwfpzu920

      2017-03-03 16:02

    • openresty 前端开发进阶一之http后端 - -外星人-

      openresty 前端开发进阶一之http后端 - -外星人-

      2017-01-08 09:01

    网友点评
    8