移動(dòng)端Web適配單位rem的坑你知道多少

前言

對(duì)于 rem 相信很多做移動(dòng)端頁(yè)面的大胸弟都不陌生逃片,用rem加百分比來(lái)做自適應(yīng)那是爽的不能再爽麻裳。至少切一般的h5頁(yè)面是沒(méi)多大問(wèn)題的具帮。但是今天卻讓我發(fā)現(xiàn)某個(gè)三星機(jī)下面竟然出現(xiàn)頁(yè)面顯示不正常的問(wèn)題浆劲,大部分安卓機(jī)跟蘋(píng)果機(jī)還是正常顯示的兵罢,也就是說(shuō)瞎暑,這尼瑪百分百是機(jī)型兼容性問(wèn)題彤敛。經(jīng)過(guò)查看確定了是rem引起的問(wèn)題。既然拋出了問(wèn)題了赌,那就得找原因跟解決辦法墨榄。

在這里,我首先想到的是安卓系統(tǒng)的問(wèn)題勿她,經(jīng)過(guò)各種百度袄秩,也證實(shí)了我的想法。網(wǎng)上有些人提出android4.4逢并、android4.4.4系統(tǒng)下的部分安卓機(jī)就存在rem計(jì)算失常的情況之剧。除此之外,撇開(kāi)操作系統(tǒng)不說(shuō)砍聊,部分機(jī)型還是存在這個(gè)問(wèn)題背稼,特別是三星的手機(jī)!如果你遇到了這個(gè)問(wèn)題玻蝌,那么很有可能就是三星的手機(jī)了蟹肘。私下去問(wèn)了個(gè)大牛,說(shuō)是三星的機(jī)子確實(shí)存在這么個(gè)情況俯树,主要是機(jī)子的屏幕引起的帘腹。ok,原因也知道了许饿,那么就提出解決方案阳欲。

首先,先說(shuō)說(shuō)我自己是怎么做移動(dòng)端適配工作的,其實(shí)也是摸索過(guò)來(lái)的球化,如有不正確的地方還請(qǐng)指正秽晚。

  1. 確定移動(dòng)端頁(yè)面的寬度范圍,通常我會(huì)取 320px - 768px ,一個(gè)是最小的尺寸赊窥,一個(gè)是ipad的爆惧,再往上感覺(jué)就沒(méi)必要在手機(jī)展示了狸页,也不美觀锨能。所以css的容器經(jīng)常會(huì)這樣寫(xiě),給予一個(gè)寬度范圍:
#indexContainer{
    width: 100%;
    min-width: 320px;
    max-width: 768px;
    min-height: 100%;
    font-size: .24rem;
    overflow-y: hidden;
    background-image: url(../../common/images/indexBg.png);
    background-position: 50% 0;
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

2.全局加載一個(gè)js文件芍耘,用于動(dòng)態(tài)計(jì)算html的fontSize值址遇。因?yàn)閞em是根據(jù)根節(jié)點(diǎn)html的字體大小而動(dòng)態(tài)改變的,所以不同寬度下計(jì)算得到不同的font-size斋竞,相應(yīng)地就可以用rem去作為頁(yè)面元素的長(zhǎng)度單位實(shí)現(xiàn)自適應(yīng)了倔约。下面是基于美術(shù)稿720px所寫(xiě)的計(jì)算fontSize的js:

(function(_D){
        var _self = {};
        _self.resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
        _self.Html = _D.getElementsByTagName("html")[0];
        _self.widthProportion = function(){
            var p = Number((_D.body&&_D.body.clientWidth||_self.Html.offsetWidth)/720).toFixed(3);
            return p>1.067?1.067:p<0.444?0.444:p;
        };
        _self.changePage = function(){
            _self.Html.setAttribute("style","font-size:"+_self.widthProportion()*100+"px");
        };
        _self.changePage();
        if (!document.addEventListener) return;
        window.addEventListener(_self.resizeEvt,_self.changePage,false);
        document.addEventListener('DOMContentLoaded', _self.changePage, false);
})(document);

解釋下上面的代碼,widthProportion 函數(shù)是用來(lái)返回當(dāng)前與設(shè)計(jì)稿(720px)的比率的坝初。因?yàn)轫?yè)面存在一個(gè)寬度范圍浸剩,即(320px - 768px), 所以在這兩個(gè)臨界點(diǎn)大于取大,小于取小鳄袍。這樣 頁(yè)面放到很大或者很小的時(shí)候字體大小也有個(gè)臨界值绢要。監(jiān)聽(tīng) resize事件和DomContentLoaded事件,從而改變字體大小拗小。即 changePage 函數(shù)重罪。font-size最后乘以100是為了方便計(jì)算rem。如拿到720px的設(shè)計(jì)稿哀九,高度250px就對(duì)應(yīng)2.5rem剿配。

3.經(jīng)過(guò)實(shí)踐,發(fā)現(xiàn)部分安卓機(jī)出現(xiàn)的該問(wèn)題大多是rem計(jì)算出來(lái)的font-size總是要比預(yù)期要大一些阅束,甚至聽(tīng)說(shuō)部分三星的手機(jī)還有計(jì)算出來(lái)比預(yù)期小的情況呼胚,這簡(jiǎn)直是駭人聽(tīng)聞。參考網(wǎng)上各種方法息裸,最后綜合提出一種最為穩(wěn)妥的處理方法蝇更,就是在計(jì)算font-size值時(shí)多一步判斷來(lái)進(jìn)行頁(yè)面font-size的reset。代碼經(jīng)改動(dòng)如下:

(function(_D){
        var _self = {};
        _self.resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
        _self.Html = _D.getElementsByTagName("html")[0];
        _self.widthProportion = function(){
            var p = Number((_D.body&&_D.body.clientWidth||_self.Html.offsetWidth)/720).toFixed(3);
            return p>1.067?1.067:p<0.444?0.444:p;
        };
        _self.changePage = function(){
            _self.Html.setAttribute("style","font-size:"+_self.widthProportion()*100+"px");
            _self.correctPx();
        };
        _self.correctPx = function(){
            var docEl = document.documentElement;
            var clientWidth = docEl.clientWidth;
            if (!clientWidth || clientWidth > 768) return;
            var div = document.createElement('div');
            div.style.width = '1.4rem';
            div.style.height = '0';
            document.body.appendChild(div);
            var ideal = 140 * clientWidth / 720;
            var rmd = (div.clientWidth / ideal);
            console.log(rmd);
            if(rmd > 1.2 || rmd < 0.8){
                docEl.style.fontSize = 100 * (clientWidth / 720) / rmd + 'px';
                document.body.removeChild(div);
            }

        };
        _self.changePage();
        if (!document.addEventListener) return;
        window.addEventListener(_self.resizeEvt,_self.changePage,false);
        document.addEventListener('DOMContentLoaded', _self.changePage, false);
})(document);

對(duì)比上面界牡,多加了個(gè)correctPx函數(shù)簿寂。在每次計(jì)算完頁(yè)面的fontSize后,對(duì)某個(gè)實(shí)際元素的大小進(jìn)行判斷宿亡,如果對(duì)比原來(lái)的比例有0.2以上的出入常遂,那就用這個(gè)比例去重新設(shè)置頁(yè)面的fontSize。如果是正常情況挽荠,就不會(huì)執(zhí)行頁(yè)面fontSize重新這一步克胳。至此平绩,問(wèn)題也算是解決了。

總結(jié)

對(duì)比設(shè)置css來(lái)控制html的font-size我覺(jué)得用js來(lái)控制更為簡(jiǎn)潔漠另,而且代碼改動(dòng)量小捏雌。在做移動(dòng)端適配的時(shí)候比較容易忽略的點(diǎn)是給頁(yè)面設(shè)置一個(gè)寬度范圍,還有就是怎樣根據(jù)ui給你的設(shè)計(jì)稿做出高保真的頁(yè)面笆搓。安卓機(jī)兼容這塊坑還是太多了性湿。能填一個(gè)是一個(gè)吧,惡心满败。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肤频,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子算墨,更是在濱河造成了極大的恐慌宵荒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件净嘀,死亡現(xiàn)場(chǎng)離奇詭異报咳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)挖藏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)暑刃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人熬苍,你說(shuō)我怎么就攤上這事稍走。” “怎么了柴底?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵婿脸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我柄驻,道長(zhǎng)狐树,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任鸿脓,我火速辦了婚禮抑钟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘野哭。我一直安慰自己在塔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拨黔。 她就那樣靜靜地躺著蛔溃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贺待,一...
    開(kāi)封第一講書(shū)人閱讀 51,610評(píng)論 1 305
  • 那天徽曲,我揣著相機(jī)與錄音,去河邊找鬼麸塞。 笑死秃臣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的哪工。 我是一名探鬼主播奥此,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼正勒!你這毒婦竟也來(lái)了得院?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤章贞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后非洲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸭限,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年两踏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了败京。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梦染,死狀恐怖赡麦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情帕识,我是刑警寧澤泛粹,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站肮疗,受9級(jí)特大地震影響晶姊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伪货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一们衙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碱呼,春花似錦蒙挑、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春蜓谋,著一層夾襖步出監(jiān)牢的瞬間梦皮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工桃焕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剑肯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓观堂,卻偏偏與公主長(zhǎng)得像让网,于是被迫代替她去往敵國(guó)和親酣衷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子事期,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容