最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美。
其结构明晰,高内聚、低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷、渐进增强)优雅的处理能力以及 Ajax 等方面周到而强大的定制功能无不令人惊叹。
另外,阅读源码让我接触到了大量底层的知识。对原生JS 、框架设计、代码优化有了全新的认识,接下来将会写一系列关于 jQuery 解析的文章。
我在 github 上关于 jQuery 源码的全文注解,感兴趣的可以围观一下。jQuery v1.10.2 源码注解 。
言归正传,本文讲的是原生 JS 获取、设置元素最终样式的方法。可能平时框架使用习惯了,以 jQuery 为例,使用 .css() 接口就能便捷的满足我们的要求。再看看今天要讲的 window.getComputedStyle ,就像刚接触 JS 的时候,看到 document.getElementById 一样,名字都这么长,顿生怯意。不过莫慌,我觉得如果我们不是只想做一个混饭吃的前端,那么越是底层的东西,如果能够吃透它,越是能让人进步。
getComputedStyle 与 getPropertyValue
getComputedStyle 为何物呢,DOM 中 getComputedStyle 方法可用来获取元素中所有可用的css属性列表,以数组形式返回,并且是只读的。IE678 中则用 currentStyle 代替 。
假设我们页面上存在一个 id 为 id 的元素,那么使用 getComputedStyle 获取元素样式就如下图所示:
1 2 3 4 |
// 语法: // 在旧版本之前,第二个参数“伪类”是必需的,现代浏览器已经不是必需参数了 // 如果不是伪类,设置为null, window.getComputedStyle("元素", "伪类"); |
尝试一下之后可以看到,window.getComputedStyle 获取的是所有的样式,如果我们只是要获取单一样式,该怎么做呢。这个时候就要介绍另一个方法 — getPropertyValue 。
用法也很简单:
1 2 3 |
// 语法: // 使用 getPropertyValue 来指定获取的属性 window.getComputedStyle("元素", "伪类").getPropertyValue(style); |
IE 下的 currentStyle 与 getAttribute
说完常规浏览器,再来谈谈老朋友 IE ,与 getComputedStyle 对应,在 IE 中有自己特有的 currentStyle 属性,与 getPropertyValue 对应,IE 中使用 getAttribute 。
和 getComputedStyle 方法不同的是,currentStyle 要获得属性名的话必须采用驼峰式的写法。也就是如果我需要获取 font-size 属性,那么传入的参数应该是 fontSize。因此在IE 中要获得单个属性的值,就必须将属性名转为驼峰形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// IE 下语法: // IE 下将 CSS 命名转换为驼峰表示法 // font-size --> fontSize // 利用正则处理一下就可以了 function camelize(attr) { // /-(w)/g 正则内的 (w) 是一个捕获,捕获的内容对应后面 function 的 letter // 意思是将 匹配到的 -x 结构的 x 转换为大写的 X (x 这里代表任意字母) return attr.replace(/-(w)/g, function(all, letter) { return letter.toUpperCase(); }); } // 使用 currentStyle.getAttribute 获取元素 element 的 style 属性样式 element.currentStyle.getAttribute(camelize(style)); |
style 与 getComputedStyle
必须要提出的是,我们使用 element.style 也可以获取元素的CSS样式声明对象,但是其与 getComputedStyle 方法还是有一些差异的。
首先,element.style 是可读可写的,而 getComputedStyle 为只读。
其次,element.style 只可以获取 style 样式上的属性值,而无法得到所有的 CSS 样式值,什么意思呢?回顾一下 CSS 基础,CSS 样式表的表现有三种方式,
- 内嵌样式(inline Style) :是写在 HTML 标签里面的,内嵌样式只对该标签有效。
- 内部样式(internal Style Sheet):是写在 HTML 的 标签里面的,内部样式只对所在的网页有效。
- 外部样式表(External Style Sheet):如果很多网页需要用到同样的样式(Styles),将样式(Styles)写在一个以 .CSS 为后缀的 CSS 文件里,然后在每个需要用到这些样式(Styles)的网页里引用这个 CSS 文件。
而 element.style 只能获取被这些样式表定义了的样式,而 getComputedStyle 能获取到所有样式的值(在不同浏览器结果不一样,chrome 中是 264,在 Firefox 中是238),不管是否定义在样式表中,譬如:
1 2 3 4 5 6 7 8 9 10 11 |
<style> #id{ width : 100px; float:left; } </style> var elem = document.getElementById('id'); elem.style.length // 2 window.getComputedStyle(elem, null).length // 264 |
getComputedStyle 与 defaultView
window.getComputedStyle 还有另一种写法,就是 document.defaultView.getComputedStyle 。
两者的用法完全一样,在 jQuery v1.10.2 中,使用的就是 window.getComputedStyle 。如下
也有特例,查看 stackoverflow ,上面提及到在 Firefox 3.6 ,不使用 document.defaultView.getComputedStyle 会出错。不过毕竟 FF3.6 已经随历史远去,现在可以放心的使用 window.getComputedStyle。
用一张图总结一下:
原生JS实现CSS样式的get与set
说了这么多,接下来将用原生 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 中要设置透明度的话,有两个方法:
- alpha(opacity=0.5)
- filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc’, endColorstr = ‘#ddddd’ );
因此在 IE 环境下,我们需要针对透明度做一些处理。先写一个 IE 下获取透明度的方法:
1 2 3 4 5 6 7 8 9 10 11 雅的处理能力以及 Ajax 等方面周到而强大的定制功能无不令人惊叹。
另外,阅读源码让我接触到了大量底层的知识。对原生JS 、框架设计、代码优化有了全新的认识,接下来将会写一系列关于 jQuery 解析的文章。 我在 github 上关于 jQuery 源码的全文注解,感兴趣的可以围观一下。jQuery v1.10.2 源码注解 。
言归正传,本文讲的是原生 JS 获取、设置元素最终样式的方法。可能平时框架使用习惯了,以 jQuery 为例,使用 .css() 接口就能便捷的满足我们的要求。再看看今天要讲的 window.getComputedStyle ,就像刚接触 JS 的时候,看到 document.getElementById 一样,名字都这么长,顿生怯意。不过莫慌,我觉得如果我们不是只想做一个混饭吃的前端,那么越是底层的东西,如果能够吃透它,越是能让人进步。
getComputedStyle 与 getPropertyValue getComputedStyle 为何物呢,DOM 中 getComputedStyle 方法可用来获取元素中所有可用的css属性列表,以数组形式返回,并且是只读的。IE678 中则用 currentStyle 代替 。 假设我们页面上存在一个 id 为 id 的元素,那么使用 getComputedStyle 获取元素样式就如下图所示:
尝试一下之后可以看到,window.getComputedStyle 获取的是所有的样式,如果我们只是要获取单一样式,该怎么做呢。这个时候就要介绍另一个方法 — getPropertyValue 。 用法也很简单:
IE 下的 currentStyle 与 getAttribute 说完常规浏览器,再来谈谈老朋友 IE ,与 getComputedStyle 对应,在 IE 中有自己特有的 currentStyle 属性,与 getPropertyValue 对应,IE 中使用 getAttribute 。 和 getComputedStyle 方法不同的是,currentStyle 要获得属性名的话必须采用驼峰式的写法。也就是如果我需要获取 font-size 属性,那么传入的参数应该是 fontSize。因此在IE 中要获得单个属性的值,就必须将属性名转为驼峰形式。
style 与 getComputedStyle 必须要提出的是,我们使用 element.style 也可以获取元素的CSS样式声明对象,但是其与 getComputedStyle 方法还是有一些差异的。 首先,element.style 是可读可写的,而 getComputedStyle 为只读。 其次,element.style 只可以获取 style 样式上的属性值,而无法得到所有的 CSS 样式值,什么意思呢?回顾一下 CSS 基础,CSS 样式表的表现有三种方式,
而 element.style 只能获取被这些样式表定义了的样式,而 getComputedStyle 能获取到所有样式的值(在不同浏览器结果不一样,chrome 中是 264,在 Firefox 中是238),不管是否定义在样式表中,譬如:
getComputedStyle 与 defaultView window.getComputedStyle 还有另一种写法,就是 document.defaultView.getComputedStyle 。 两者的用法完全一样,在 jQuery v1.10.2 中,使用的就是 window.getComputedStyle 。如下
也有特例,查看 stackoverflow ,上面提及到在 Firefox 3.6 ,不使用 document.defaultView.getComputedStyle 会出错。不过毕竟 FF3.6 已经随历史远去,现在可以放心的使用 window.getComputedStyle。 用一张图总结一下:
原生JS实现CSS样式的get与set 说了这么多,接下来将用原生 JS 实现一个小组件,实现 CSS 的 get 与 set,兼容所有浏览器。 完整的组件代码在我的 github 上,戳我直接看代码。
getStyle(elem, style) 对于 CSS 的 set ,对于支持 window.getComputedStyle 的浏览器而言十分简单,只需要直接调用。
反之,如果是 IE 浏览器,则有一些坑。
opacity 透明度的设定 在早期的 IE 中要设置透明度的话,有两个方法:
因此在 IE 环境下,我们需要针对透明度做一些处理。先写一个 IE 下获取透明度的方法: |