兩年移動端前端開發問題吐血彙總

DOM哥發表於2018-09-30

手機固有 bug

  • 某些手機上 fixed 元素在頁面滾動時會消失

使用區域性滾動,而不是整頁滾動

  • 某些 IOS 裝置上觸發不了點選事件

在元素上加 pointer:cursor

  • IOS 裝置上點選事件有 300ms 延遲

兩種方法,一是使用 fastclick.js(推薦)。二是不綁 click 事件,綁在 tap 事件上(此方法會導致開發時除錯困難,模擬裝置模式下觸發 tap 有 bug)

  • IOS 裝置上 fixed 元素在鍵盤彈起時位置會變幻不定

沒有很好的解決方案,應從產品設計層面避免這種情況(比如說做轉場頁面等)

  • 在彈窗上滑動時底部頁面也跟著動

在彈窗上需要滾動的地方使用 Swiper,不需要滾動的地方加 ontouchmove="event.preventDefault()"

  • 某些 IOS 裝置上頁面滾動時不會連續觸發 scroll 事件

綁在 touchmove 事件上,但手指離開螢幕慣性滑動這段時間還是無法觸發,如果確實需要精細控制,可考慮 IScroll.js

  • 瀏覽器重新整理頁面後會記憶之前的滾動條位置

這通常可以提升使用者體驗,但有時我們需要禁止這種記憶,加上下面兩行

history.scrollRestoration = `manual`
window.onunload = () => window.scrollTo(0, 0)
  • h5 video 無法自動播放

無法實現,無法實現,無法實現。這是廠商為避免偷取流量強制規定的。兩個方法,一是從產品設計層面規避,二是降級為使用者觸屏播放,沒有第三種可能

相容性部分

  • Array.prototype.sort 方法在某些手機上會不起作用

sort 方法傳入的比較函式應該返回一個數值,而不是布林值。也就是應該使用 - 號,而不是 ><

  • Object.assign 方法在某些手機上會不起作用

參考 jQuery 的 $.extend 實現自己的物件合併方法。注意,Babel 僅轉譯語法,而不轉譯 API,所以使用這些 ES6+ 的 API 都存在不相容的風險,如果引入了 Babel 的 polyfill,那就不用擔心,否則就需要自己 polyfill

  • CSS3 特性(flex 佈局,transform 等)不支援

加上字首,加上字首,加上字首。加完字首不敢說 100% 支援吧,90% 還是有保證的,尤其是移動端。手動加是不可能手動加的,可使用 autoprefixer 配合構建工具處理

  • 1 畫素問題

這裡的1畫素並非1邏輯畫素(也就是CSS畫素),而是1物理畫素,可以採用縮放的方法實現,首先設定 width: 1px,然後使用媒體查詢根據不同的dpr縮放不同的比例,貼一下 less 的實現

.one-x { height: 1px;}
.one-y { width: 1px; }

@dpr: 1.5, 2, 3;
@len: length(@dpr) + 1;
.genScale(@n: 1) when (@n < @len) {
  @val: extract(@dpr, @n);
  @media (min-device-pixel-ratio: @val) {
    .one-x {
      transform: scaleY(1/@val);
    }

    .one-y {
      transform: scaleX(1/@val);
    }
  }
  .-fix-less-compiler-bug- {
    display: block;
  }
  .genScale(@n + 1);
}

.genScale();
  • 吸頂問題

IOS 直接使用 position: sticky,安卓機型綁 scroll 事件。(需要提一句的是,IOS 的 scroll 事件觸發不連續,安卓對 sticky 的支援不太好。所以上面的方法是比較科學地)附上機型判斷程式碼

const ua = window.navigator.userAgent.toLowerCase()
const isAndroid = /android/.test(ua)
const isIOS = /iphone|ipad|ipod/.test(ua)

庫 & 框架

  • jQuery 的 ajax 方法傳參 data 項問題

data 的 key/value 鍵值對的 value 為 undefined 時 jQuery 會直接不傳這一條,為 null 時傳空字串

  • Vue 修改了資料物件檢視不更新

就是不更新,就是不更新,就是不更新。這個官網還有寫了。這個和 Vue 監測資料變化的機制有關。Vue 無法檢測到物件的新增屬性和 vm.arr[index] = newVal 這種方式更新的陣列變化。可用以下方法觸發

vm.arr = [ ...vm.arr ]
vm.obj = { ...vm.obj }

細節

  • IOS 區域滾動卡頓不絲滑

加上 -webkit-overflow-scrolling: touch

  • 某些手機上點選時元素高亮閃一下

加上 -webkit-tap-highlight-color: rgba(0, 0, 0, 0)

  • 隱藏滾動條

加上 ::-webkit-scrollbar{ display: none }

—————————- 我是結束線 —————————-

暫時就這些了,更多的以後更新

相關文章