1. 程式人生 > >移動端踩坑合集

移動端踩坑合集

額外 如果 美的 for循環 走了 發生 成本 res 也會

前段時間在小密圈和大家分享我的感受,H5代替客戶端進行移動端開發,是大趨勢。未來較長一段時間,是混合應用的天下。然而H5寫移動頁面,那絕對是一步一個坑的節奏啊,做好各設備的兼容將是各前端er的重要使命。今天給大家送上一個合集,是我最近開發中遇到的一些坑,作個記錄,也給大家一些經驗。

1.

babel-polyfill老實加上。現在很多項目都用ES6在寫了,ES6在移動端的兼容也天生較好。有些同學嫌棄polyfill文件太大(壓縮後也將近100KB)就不引了,反正用到的方法也不多。

然而最近發現項目在魅族手機上報錯,查看原因發現是沒有Array.includes方法,而該項目也正是我說的沒引babel-polyfill的情況。所以,為了保險起見,還是老實引入吧。當然也可以按需引入對應方法,這樣的話成本又高了,你沒法預見項目將來還會用哪個方法。

2.

同事反饋,ios上某個頁面,輸入框裏一輸東西就閃退。我當時詫異,一個輸入框怎麽有本事把應用給搞崩。

經排查,原因令人大跌眼鏡。場景是這樣的:在點擊input標簽的時候,根據一些邏輯來判斷是否應該給加readonly屬性。在手機上,點擊動作可能有延遲,在邏輯判斷生效之前,鍵盤已經彈出來了,然後input才被設為readonly。此時如果用鍵盤輸入東西,系統就直接閃退了!沒錯,是閃退了。因為你在往一個readonly的輸入框裏寫東西。

當然這裏也是邏輯的問題,一個input框,應該在其被點擊之前,就把readonly屬性確定好的。

3.

forEach去循環NodeList不靠譜。querySelectorAll返回的是NodeList類型,而forEach是Array上面的方法。大部分瀏覽器有做兼容,用forEach去循環NodeList這樣的類數組,也是能幹活的。

然而也不是百分百,發現在vivo手機上就不行,直接報錯。所以還得老實用for循環去取。有人說可以先把類數組轉成數組呀,但我覺得為了循環而轉,反而產生額外的開銷。

4.

fixed定位在iOS的不完全支持。大家知道iOS原先是不支持fixed定位的,在後來的系統版本中做了支持。

但是在最近的測試中發現,當fixed元素的內容很多,既DOM節點嵌套非常多的時候,fixed元素在一頓亂滑的操作下,竟然被滑走了!可見在最新的iOS10下,fixed的支持也是不完美的啊。

所以我一般用absolute定位+局部div滾動來實現固定定位。

5.

click能點透,也能上冒。click事件點透的現象,做移動端開發的同學應該知道,前幾年網上也很多分析文章。其實核心問題就是,在事件派發的過程中,當前點擊元素突然消失,導致事件被“嫁接”在了別的元素上。

最近遇到的一個坑是,當一個元素綁定了touchstart事件,如果點擊的過程中,頁面突然彈出一個層,那麽click事件也會發生在這個層上面,感覺像上冒了一樣。

6.

這個問題,是為了解決5而引出的。我嘗試給touchstart事件加了preventDefault,結果整個頁面滾不動了。原因是把默認的scroll動作給禁止了。看來是不能隨意給touchstart事件加preventDefault的。

7.

vue在iOS上的性能缺陷?項目整體用了vue,發現某些特定的操作,在iOS上有明顯的延遲。我不敢確診是vue的問題,只是就表象來做總結。

存儲在store中的數據,在組件中進行watch,發現更新會緩慢。

頻繁修改數據的綁定,比如audio的progress事件,頁面進行style綁定的時候,當系統多次鍵盤彈出後,實時更新會失效,我不得不手工操作DOM。

給事件用了修飾符,比如.stop/.prevent,監聽函數的執行有明顯延遲。

8.

按home鍵切入後臺後的情況。iOS和安卓都要註意,可能需要處理的東西有:延遲延時是否還是執行、音頻是否能繼續播放、Promise鏈是否在繼續執行。

如頁面有以上操作,需要註意一下,在按home鍵進入後臺,再返回的時候頁面是否還正常。

相應的處理辦法,有Page Visibility API,但是要考慮兼容。最好是讓殼來提供API,這樣比較穩妥。

9.

vue組件的銷毀。vue組件有$destroy方法,一般不用,但是如果要用到,註意它只是銷毀Vue實例。在store中存儲的相關狀態,需要手動去重置。頁面上的HTML節點,需要手工去刪除。

10.

vuex自動註冊問題。這個跟移動端關系不大,也是遇到的,一並說吧。

vuex會自動檢測是否有全局的Vue變量,有的話會自動註冊。如果你在代碼中再次use,則會報錯。我嘗試想辦法檢測vue是否已註冊了vuex,但是沒找到方法。最後只得這樣來判斷:if(window.Vue && window.Vuex)。這樣表明vuex肯定已被註冊過了。

移動端踩坑合集