解決移動端一像素問題的Vue指令

最近公司項目要解決一像素問題,本身琢磨了一陣子而且網上搜索了一堆博客,總結出最好的辦法應該是經過css的transform scale縮放1px的內容來模擬設備上1px的效果了。可是這個方法有太多侷限。而後秉着css解決不了的問題就用js來解決的原則,而後結合vue的自定義指令,手擼了一個一像素vue自定義指令。打算扔到giuhub留存。順便總結一下遇到的問題。css

項目地址:https://github.com/HelloWorld20/onepxhtml

歡迎各位取用。若有錯誤的地方,也歡迎指正。vue

緣由

衆所周知,自從iPhone 4帶來了Retina display後,移動端開始引入了一個叫設備像素比(devicePixelRatio)的東西。git

另外一方面,若是給一個html標籤寫一個小於1px(H5)的border;IOS能夠正常渲染,可是安卓設備不渲染。因此是不能用正常的方法來讓安卓設備渲染一個1物理像素的線。github

戳這裏看DEMO;web

固然用移動端才能看到效果:segmentfault

qrcode

網上的解決方案

網上搜能搜出不少解決方案,這篇文章基本彙總了網上的全部方案。而後結論是:使用css的僞元素來渲染一個1px(H5)的div,而且使用CSS3的scale來縮放dpr倍,從而渲染一個1px物理像素的線。dom

然而理論畢竟理論,用到項目中的時候仍是遇到了不少問題wordpress

1. 若是兩個僞元素都被佔用,則沒法實現

網上的方案都是用CSS僞元素來實現的,而僞元素只有before和after兩個,因此要是實際開發中中佔用了before、after,則沒法用CSS來實現模擬一像素。spa

2. 必須手動設置圓角

圓角是最頭疼的問題。用CSS僞元素雖然能夠作到圓角,可是CSS僞元素只能經過border-radius: inherit獲得和父元素同樣值的圓角大小,縮放以後就不同了,且css沒法計算縮放後還和父元素同樣的圓角。並且js也不能操做CSS僞元素,因此不得不手動計算dpr,而後給CSS僞元素設置圓角。

3. -webkit-device-pixel-ratio不是標準方法

MDN

CSS中判斷設備設備像素比的方法是-webkit-device-pixel-ratio,不是標準的方法,因此用起來心慌慌。而JS的window.devicePixelRatio已經全面支持,頂多也就一個undefined。徹底不用擔憂兼容性問題。

4. 部分標籤不能設置僞元素

type爲text的input標籤就沒法在標籤內插入的dom(雖然控制檯裏顯示已經被插入,可是不會被渲染出來),因此僞元素也沒法給其加上模擬的1像素。

some text you can't see

更好的方案

本着CSS解決不了的問題就用JS來解決的思想。再結合Vue提供的自定義指令,能夠在想要加1像素的html標籤上加上一個指令,js能經過Vue的自定義指令拿到對應的DOM,那麼就一切皆有可能。

最終實現了一個Vue指令,只須要給對應的HTML標籤加上一條指令就行。其餘的Vue指令自動處理。而且這個指令在咱們項目中運行過一段時間,基本是可靠的。

要注意的地方

  • 綁定的元素必須顯示聲明其position值爲:relative、fixed、absolute之一,否則模擬一像素的div沒法定位到位置
  • 務必給對應的DOM清除掉border樣式
  • 不能用於<input type="text" />標籤等內部不能插入元素的標籤
相關文章
相關標籤/搜索