天天看点

REM移动适配问题与淘宝移动端脚本

我们在CSS中不仅仅有px或者百分比这样的单位,还有vh/vw,以及rem等

rem是一个相对的单位,是相对于HTML标签字号来计算结果

1rem = 1HTML字号大小

那么我们怎么设置HTML标签字号?

html{font-size:20px};
           

 不过我们还是不要自定义设计为好,因为大家公认在rem布局方案中,将网页分为10等份,HTML标签字号为视口宽度的1/10

如果我们想要自定义一个响应式布局的话,可以使用媒体查询:

@media (width: 320px) {
    html{
        font-size: 32px;
    }
}


//意思就是当页面宽度等于320px的时候,就会使用媒体查询中的CSS属性

//媒体查询
@media (媒体特性) {
    选择器{
        CSS属性;
    }
}
           
@media (min-width: 320px) {
    html{
        font-size: 32px;
    }
}

//当页面宽度大于320px时,使用该媒体查询CSS属性
           

当然,我们也可以使用现成的淘宝为我们提供的JS脚本:flexible.js

使用该JS文件可以配合rem实现在不同的宽度设备中,网页元素尺寸等比缩放效果

该JS本质也就是根据不同的视口宽度给网页中html根结点设置不同的font-size

我编写了一些注释,便于理解:

(function flexible(window,document){
    //获取html的根元素
    var docEL = document.documentElement;
    //dpr物理像素比(如果浏览器有devicePixelRatio像素比元素就输出devicePixelRatio,如果没有,就定义像素比为1)
    var dpr = window.devicePixelRatio || 1;

    //adjust body font size 设置我们body的字体大小
    function setBodyFontSize(){
        //如果页面中有body这个元素,就设置body的字体大小
        if(document.body){
            document.body.style.fontSize = (12 * dpr) + 'px';
        }else{
            //如果页面中没有body这个元素,则等我们页面主要的DOM元素加载完毕再去设置body的字体大小
            document.addEventListener('DOMContentLoaded',setBodyFontSize);
        }
    }
    setBodyFontSize();

    //set 1rem = viewWidth / 10   设置我们html元素的文字大小
    function setRemUnit(){
        //html宽度分为1/10,每一等份就是一个rem
        var rem = docEL.clientWidth / 10;
        docEL.style.fontSize = rem + 'px';
    }
    setRemUnit();

    //reset rem unit on page resize 当页面尺寸大小发生变化时,重新设置rem大小
    //当resize页面大小发生变化,重新执行setRemUnit获取rem大小
    window.addEventListener('resize',setRemUnit);
    //往返缓存:保存这页面的数据,DOM和JavaScript的状态,实际来说是将整个页面都保存在了内存里
    //pageshow是我们重新加载页面触发的事件,如果使用load的话,火狐浏览器的往返缓存是不会改变rem大小的
    window.addEventListener('pageshow',function(e){
        //pageshow的persisted值返回true,就是说如果页面是从缓存取过来的页面,也需要重新计算一下rem大小
        if(e.persisted){
            setRemUnit();
        }
    })

    //detect 0.5px supports 有些移动端的浏览器不支持0.5像素的写法
    if(dpr >= 2){
        var fakeBody = document.createElement('body');
        var testElement = document.createElement('div');
        testElement.style.border = '5px solid transparent';
        fakeBody.appendChild(testElement);
        docEL.appendChild(fakeBody);
        if(testElement.offsetHeight === 1){
            docEL.classList.add('hairlines');
        }
        docEL.removeChild(fakeBody);
    }
}(window,document));
           

继续阅读