使用JavaScript达成 background-size: cover 的效果

发布于:2019-10-28

最近有一个项目,领导要求:要让一个视频一屏显示的情况下不能改变宽高比 and 适配各种分辨率 and 兼容到IE 7。嘶~,有点棘手,对于要兼容到IE 7的项目,写CSS简直头疼。

不过不是我做(欸嘿),别人也没做出来,我也没站出来(面子最重要),于是领导不得不放低要求,当然这都是后话了。

后来想,如果我来做的话,我会怎么做?对于领导的要求,我脑子里第一个闪过的就是background-size: cover这个玩意儿,但是第一,这个是CSS 3的属性,IE 8就歇菜了,更别说IE 7了,第二,这个属性只对图片有用……

那能不能用js来模拟呢?

说干就干,当下就开始研究cover属性是怎么工作的,最后结论是:

cover在正常情况下,只是单纯的将图片宽度放到与容器一样宽,在缩放过程中,当图片高度小于容器高度时会根据原始图片的宽高比(ratio)来放大图片宽度,使原始图片始终撑满容器。

听起来有点绕,直接上代码:

;(function(w) {
    var kkkover = function () {
        _ = this;
        this.init = function (obj) {
            w.onresize = function () {
                _.resized(obj);
            }
            obj.img.onload = function () {
                obj.ratio = obj.img.clientHeight / obj.img.clientWidth;
                _.calcStyle(obj);
            }
            obj.ratio = obj.img.clientHeight / obj.img.clientWidth;
            _.calcStyle(obj);
        }
        this.calcStyle = function (obj) {
            obj.wrapCell.style.position = 'relative';
            obj.img.style.position = 'absolute';
            obj.img.style.top = '50%';
            obj.img.style.zIndex = '0';
            obj.img.style.left = '50%';
            obj.img.style.width = '100%';
            obj.img.style.marginLeft = -(obj.img.clientWidth / 2) + 'px';
            obj.img.style.marginTop = -(obj.img.clientHeight / 2) + 'px';
            if(obj.img.clientHeight <= obj.wrapCell.clientHeight){
                obj.img.style.maxWidth = 'none';
                obj.img.style.height = obj.wrapCell.clientHeight;
                obj.img.style.width = obj.wrapCell.clientHeight / obj.ratio + 'px';
                obj.img.style.marginTop = -(obj.img.clientHeight / 2) + 'px'
                obj.img.style.marginLeft = -(obj.img.clientWidth / 2) + 'px';
            }
            if(obj.wrapCell.clientWidth > obj.img.clientWidth){
                obj.img.style.width = '100%';
                obj.img.style.height = 'auto';
                obj.img.style.marginLeft = -(obj.img.clientWidth / 2) + 'px';
                obj.img.style.marginTop = -(obj.img.clientHeight / 2) + 'px';
            }
        }
        this.resized = function (obj) {
            _.calcStyle(obj);
        }
    }
    var app = new kkkover();
    var wp = w.prototype || w.__proto__ || w;
    wp.kkkover = app.init;
}(window));

使用的话大概就是这样:

<div id="test">
    <img src="path/to/img" id="test_img">
</div>
kkkover({
    wrapCell: document.getElementById('test'), // 传入容器
    img: document.getElementById('test_img') // 传入容器中的图片
});

可以在这里看一下演示。代码已经测试,可以兼容到IE 7。

对于视频也是一样的用法,img传视频元素就可以了。

将这篇文章分享到推特 订阅全文RSS

Comments

评论加载中...
好惨一男的,一条评论都没有...
预览
加载中...
# 发表您的评论
发布
预览
关闭当前窗口