欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解析原生JS getComputedStyle

程序员文章站 2022-06-25 16:49:30
getcomputedstyle 与getpropertyvaluegetcomputedstyle 为何物呢,dom 中 getcomputedstyle 方法可用来获取元素中所有可用的css属性列...

getcomputedstyle 与getpropertyvalue

getcomputedstyle 为何物呢,dom 中 getcomputedstyle 方法可用来获取元素中所有可用的css属性列表,以数组形式返回,并且是只读的。ie678 中则用 currentstyle 代替 。

假设我们页面上存在一个 id 为 id 的元素,那么使用getcomputedstyle 获取元素样式就如下图所示:

解析原生JS getComputedStyle

尝试一下之后可以看到,window.getcomputedstyle 获取的是所有的样式,如果我们只是要获取单一样式,该怎么做呢。这个时候就要介绍另一个方法 --getpropertyvalue。

用法也很简单:

// 语法:
// 使用 getpropertyvalue 来指定获取的属性
window.getcomputedstyle("元素", "伪类").getpropertyvalue(style);

ie 下的 currentstyle与getattribute

说完常规浏览器,再来谈谈老朋友 ie ,与getcomputedstyle 对应,在 ie 中有自己特有的 currentstyle属性,与 getpropertyvalue 对应,ie 中使用getattribute 。

和 getcomputedstyle 方法不同的是,currentstyle 要获得属性名的话必须采用驼峰式的写法。也就是如果我需要获取 font-size 属性,那么传入的参数应该是 fontsize。因此在ie 中要获得单个属性的值,就必须将属性名转为驼峰形式。

// 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 样式表的表现有三种方式,

1.内嵌样式(inline style) :是写在 html 标签里面的,内嵌样式只对该标签有效。

2.内部样式(internal style sheet):是写在 html 的 <style> 标签里面的,内部样式只对所在的网页有效。

3.外部样式表(external style sheet):如果很多网页需要用到同样的样式(styles),将样式(styles)写在一个以 .css为后缀的 css 文件里,然后在每个需要用到这些样式(styles)的网页里引用这个 css 文件。

而element.style 只能获取被这些样式表定义了的样式,而 getcomputedstyle 能获取到所有样式的值(在不同浏览器结果不一样,chrome 中是 264,在 firefox 中是238),不管是否定义在样式表中,譬如:

<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 。如下

解析原生JS getComputedStyle

也有特例,查看*,上面提及到在firefox 3.6 ,不使用document.defaultview.getcomputedstyle 会出错。不过毕竟 ff3.6 已经随历史远去,现在可以放心的使用window.getcomputedstyle。

用一张图总结一下:

解析原生JS getComputedStyle

原生js实现css样式的get与set

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

getstyle(elem, style)

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

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 下获取透明度的方法:

// 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的一个保留字。

所以在各浏览器中都会有代替的写法,比如说在标准浏览器中为 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 的写法,可以让我们走得更远。

以上就是解析原生js getcomputedstyle的详细内容,更多关于原生js getcomputedstyle的资料请关注其它相关文章!