摘要:今天想寫的問題來自于網(wǎng)易一面的時(shí)候,面試官問我如何在移動(dòng)端的頁面上畫一條的線。上面的結(jié)論我在端谷歌瀏覽器的設(shè)備模擬器里證實(shí)了有效,但是安卓和真機(jī)并沒有試過。
起因
最近一個(gè)月都在準(zhǔn)備校招,所以沒什么時(shí)間寫博客。今天想寫的問題來自于網(wǎng)易一面的時(shí)候,面試官問我如何在移動(dòng)端的頁面上畫一條1px的線。這個(gè)問題我模糊地記得之前看過相關(guān)文章,但是我清楚地記得當(dāng)時(shí)自己腦子一片空白。是的,一面掛了,但是這個(gè)問題一直在我回來的路上不斷想起,所以今天我就要解決這個(gè)問題,來看看有什么解決方案吧~
動(dòng)態(tài)改變viewport的縮放這是淘寶的flexible提出的解決方案,其核心就是根據(jù)window.devicePixelRatio(dpr)的值動(dòng)態(tài)改變viewport的縮放,核心代碼如下(有刪減):
if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,對(duì)于2和3的屏,用2倍的方案,其余的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其他設(shè)備下,仍舊使用1倍的方案 dpr = 1; } scale = 1 / dpr; } if (!metaEl) { metaEl = doc.createElement("meta"); metaEl.setAttribute("name", "viewport"); metaEl.setAttribute("content", "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no"); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement("div"); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } }
這個(gè)方案只對(duì)iOS的Retina屏幕做了處理,而沒有管安卓的Retina屏幕,原因可以看《再談Retina下1px的解決方案》這篇文章。使用了flexible之后直接寫1px就能實(shí)現(xiàn)效果,但是最新的2.0好像放棄了這種縮放的方案,對(duì)于1px的處理則變成了border-image或者background-image,詳細(xì)的可以看《再聊移動(dòng)端頁面的適配》。
這里再簡單談一下這種viewport縮放的原理:
首先一開始寫移動(dòng)端的時(shí)候,我是直接加一個(gè)meta標(biāo)簽 ,這個(gè)meta標(biāo)簽使得頁面寬度等于設(shè)備寬度,頁面的縮放默認(rèn)為1,且用戶不能縮放,后來看到一篇文章講viewport計(jì)算是這樣的:
viewport的默認(rèn)寬度是980px;設(shè)置了initial-scale則寬度是device-width/initial-scale;設(shè)置了width則寬度等于width的值;同時(shí)設(shè)置了initial-scale和width則寬度取兩者中較大的一個(gè)。
上面的結(jié)論我在PC端谷歌瀏覽器的設(shè)備模擬器里證實(shí)了有效,但是安卓和iOS真機(jī)并沒有試過。
transform: scale(0.5)這個(gè)方案也是WeUI正在用的,核心思想是使用transform的scale來整體縮放,如果你想畫一條1px的線,就可以直接用
div { height: 1px; background: #000; transform: scaleY(0.5); transform-origin: 0 0; }
理論上在dpr為2時(shí)就是scaleY(0.5),在dpr為3時(shí)就是scaleY(0.333),但是我注意到WeUI并沒有針對(duì)其他dpr的做特殊處理,可能是因?yàn)樵趇Phone6(dpr=2)和iPhone6 Plus(dpr=3)中看起來差別不大吧。
如果你想給一個(gè)元素加一個(gè)1px的邊框可以利用到偽元素,在這個(gè)方案下邊框加圓角也很容易實(shí)現(xiàn),具體代碼如下:
div:after { content: " "; width: 78px; height: 38px; border-radius: 4px; border: 1px solid #000; transform: scale(0.5, 0.5); transform-origin: 0 0; position: absolute; }其他方案 border-image
這種是AlloyTeam的《CSS 實(shí)現(xiàn)類似原生效果的 1px 邊框》這篇文章上看到的,代碼寫起來挺簡單,但是要自己制作圖片,而且圓角也不好弄,如果改了顏色就要對(duì)圖片處理,所以不是很好的方案。
box-shadow這個(gè)顏色不好弄,所以效果也不是很好。
div { border: none; box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5); }0.5px解決方案
div { border: 1px solid #000; } @media (-webkit-min-device-pixel-ratio: 2) { div { border: .5px solid #000; } }
安卓和iOS7之前版本碰到0.5px直接就解析成0px了,但是這一特性也是可以利用的,在最新的flexible中就有對(duì)0.5px進(jìn)行判斷的代碼:
// detect 0.5px supports 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) }小結(jié)
這篇文章從國慶開始斷斷續(xù)續(xù)地寫,到最后一天總算是寫完了,這段時(shí)間整個(gè)人心態(tài)經(jīng)歷了一些變化,主要表現(xiàn)在對(duì)待技術(shù)比以前更加踏實(shí)了,無論如何希望自己能堅(jiān)持寫博客,堅(jiān)持學(xué)習(xí)前端,相信總能找到一個(gè)理想的工作的,加油!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/116655.html
摘要:相比于傳統(tǒng)的,是一種現(xiàn)代的為準(zhǔn)備的優(yōu)質(zhì)替代方案。保護(hù)了有價(jià)值的默認(rèn)值通過為幾乎所有的元素施加默認(rèn)樣式,強(qiáng)行使得元素有相同的視覺效果。當(dāng)一個(gè)元素在不同的瀏覽器中有不同的默認(rèn)值時(shí),會(huì)力求讓這些樣式保持一致并盡可能與現(xiàn)代標(biāo)準(zhǔn)相符合。 本文譯自 http://nicolasgallagher.com/about-normalize-css/ 最初發(fā)布于我的博客:http://jerr...
摘要:前端日報(bào)精選傳送門瀏覽器性能優(yōu)化渲染性能在生產(chǎn)中的使用發(fā)送推送第期巧用匿名函數(shù)重構(gòu)你的代碼中文可持久化數(shù)據(jù)結(jié)構(gòu)以及結(jié)構(gòu)分享眾成翻譯學(xué)習(xí)筆記的模板學(xué)習(xí)筆記教程的作用域插槽教程移動(dòng)助手實(shí)踐一基于的換膚功能掘金網(wǎng)站壓力及性能測試一篇 2017-10-09 前端日報(bào) 精選 傳送門:React Portal瀏覽器性能優(yōu)化-渲染性能在生產(chǎn)中的Progressive Web App使用Service...
摘要:這個(gè)算法看似不錯(cuò)而且簡單,不過存在這一個(gè)致命傷當(dāng)兩個(gè)對(duì)象互相引用的時(shí)候,就永遠(yuǎn)不會(huì)被回收于是引用計(jì)數(shù)算法就永遠(yuǎn)回收不了這兩個(gè)對(duì)象,下面介紹另一種算法。 前言 ? 如果要問Java與其他編程語言最大的不同是什么,我第一個(gè)想到的一定就是Java所運(yùn)行的JVM所自帶的自動(dòng)垃圾回收機(jī)制,以下是我學(xué)習(xí)JVM垃圾回收機(jī)制整理的筆記,希望能對(duì)讀者有一些幫助。 哪些內(nèi)存需要回收?what? ? ...
摘要:從今天開始研究一下的異步相關(guān)內(nèi)容,感興趣的請關(guān)注同期異步系列文章推薦異步中的回調(diào)異步與異步之異步之異步之和異步之一異步之二異步實(shí)戰(zhàn)異步總結(jié)歸檔什么是異步我們知道的單線程的,這與它的用途有關(guān)。 從今天開始研究一下javascript的異步相關(guān)內(nèi)容,感興趣的請關(guān)注 同期異步系列文章推薦javascript異步中的回調(diào)javascript異步與promisejavascript異步之Prom...
摘要:瀏覽器兼容問題什么是瀏覽器兼容所謂的瀏覽器兼容性問題,是指因?yàn)椴煌臑g覽器對(duì)同一段代碼有不同的解析,造成頁面顯示效果不統(tǒng)一的情況。 瀏覽器兼容問題 1、什么是瀏覽器兼容 所謂的瀏覽器兼容性問題,是指因?yàn)椴煌臑g覽器對(duì)同一段代碼有不同的解析,造成頁面顯示效果不統(tǒng)一的情況。 2、瀏覽器兼容產(chǎn)生的原因 因?yàn)椴煌瑸g覽器使用內(nèi)核及所支持的HTML等網(wǎng)頁語言標(biāo)準(zhǔn)不同; 以及用戶客戶端的環(huán)境不同(如...
閱讀 4172·2021-11-22 13:52
閱讀 2089·2021-09-22 15:12
閱讀 1128·2019-08-30 15:53
閱讀 3463·2019-08-29 17:12
閱讀 2196·2019-08-29 16:23
閱讀 1660·2019-08-26 13:56
閱讀 1778·2019-08-26 13:44
閱讀 1896·2019-08-26 11:56