天天看點

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));
           

繼續閱讀