在做 iOS 和 Android 的 HTML5 開發時,你都掉到過哪些坑裡?

又是怎麼解決的?


我來說一個所遇到的詭異的坑。嚴格地講不算是坑,但是比坑更坑100倍,因為你一旦遇到了,壓根就沒轍。

事情是這樣的,公司有一個H5開發的遊戲。開發、測試、運營一切正常。不久聯運了,聯運在合作方的平台上。誰想一上平台就不對了,具體的問題是完全找不出問題!在我們的伺服器上一切工作正常,但是到合作方的服務上,在手機里怎麼刷新就是不工作。由於生產版本是混淆並壓縮的,所以在手機上調試及其痛苦。折騰了好幾天一直還是黑屏。簡直見了鬼了。老大做了好幾年遊戲,他說以前用主機託管的時代,開服都要給機器燒了香再送去機房。現在這個雲伺服器年代,沒法給雲伺服器燒香開光啊,咋整?!

沒法整,為了收入只能硬著頭皮繼續查。

終於一天,調試的小弟在safari 的遠程console裡面發現有一個js文件404了。但是這個js文件在CDN上存在的好好的,查了和刷了CDN節點,單獨訪問這個JS文件一切正常。 這個JS文件在我們自己的生產版本中也工作一起正常。就是在合作方的渠道里,用手機打開就404了。 把 404 具體錯誤信息 dump 下來,發給CDN供應商核對。CDN那裡反饋挺快的,答:那個IP不是他們伺服器!

見了鬼了!

把js文件改名,問題依舊,見了大鬼了

又折騰了一天,實在沒轍了。死馬當活馬醫,把JS 嵌到頁面里,工作正常了。 然後反查那個404的 ip,發現對應託管網站是廣告聯盟。 但是我們壓根沒在遊戲裡面查廣告啊。
實在摸不著頭腦,問了各路朋友。有一個做PC頁游的老大哥一語道破天機:

他說:「誰叫你們運營域名的名字裡帶 game 的。 被電信劫持了。

合作方的運營域名命中電信的劫持條件,我們的程序js文件被重定向到電信廣告系統下的一個伺服器上去。那個伺服器在回吐這個js文件內容之前,會插一堆廣告js代碼到頁面中。由於我們的遊戲是用了一個 z-index:9999 的 canvas 繪製的。所以之前電信插入的廣告被擋住了,誰也沒發現。 直到那個廣告服務壞掉的那天,頁面就拉不出來了。

不要臉的電信!!!!

從此之後,我們所有的 js 文件全部改後綴名叫 css, 改 mimetype 叫 text/plain


說一下我遇到的吧:
1、最痛恨的是紅米手機,ua返回iphone,需要結合platform判斷,但是還不準確,導致需要ios和android區別對待的時候就坑了。
2、是fixed的問題。這個解決辦法是盡量不要用,不過ios7及以下才會出現這個問題。某些情況下紅米也會有這個問題。(最近剛剛遇到,已經被坑掛了)。
3、如果你想要使用css3的動畫,那麼一定要變著方式使用3d gpu加速的方式,不要試著left,height,width這樣的元素進行變換了,android4.4以下版本卡死你。
4、ios全線點擊會有300毫秒延遲,使用fastclick解決。這個插件最良心了。
5、web app像素眼設計會糾結你1px邊框問題。解決辦法有相應知乎大牛答過。
6、qq瀏覽,uc瀏覽以及ios的瀏覽器,滾動時不會觸發scroll事件,但會觸發touchmove。當停止滾動後會出發scroll。
7、滾動有iscroll插件,但是還是使用原生的比較好。
8、meta功能要用好,禁止縮放,縮放比例,屏蔽電話號碼等功能很實用。(手機回答就不列舉了)。
9、如果想要像手機淘寶那樣的各個平台看起來展示效果一致,那麼就使用rem來做單位。
10、-webkit-tap-highlight-color可以取消點擊高亮。
11、localStorage在瀏覽器開啟無痕模式下ios會拋異常,導致js中斷。
12、一些情況下對非可點擊元素監聽click事件,ios下不會觸發,css增加cursor:pointer就搞定了。當然想要乾脆靜止點擊就是not-allowed。
13、android4.4以下版本,設置圓角屬性需要在直接元素上,向父元素設置圓角並且指定overflow:hidden是不會生效的。
##########
以上,暫時就想到這麼些,有些大家都清楚,還是混個條數寫上來了。以後再有新發現隨時補上來。
##########


來, 跟我念 : 千萬不要用 jQuery Mobile ! 千萬不要用 jQuery Mobile ! 千萬不要用 jQuery Mobile !


點擊穿透 click延遲 scroll元素臨界的bug android screen.w/h 不準 rem不準 scroll時動畫失效 animate回調 最小字型大小限制 不同機型全屏自適應 android,ios和native通訊 下載app方案ios,android,微信都不一樣 二維碼識別 太多了手機根本寫不完吃飯去了…

補個canvas殘影 drawimage 發虛等不同系統機型也表現不一致。


說下遇到過的幾個問題……

1.iPhone5以上各種應用的webview(例如微信)在遇到有大量圖片的頁面時會出現圖片亂套的情況,6和6plus更為嚴重,具體表現為各種img和background-image互相錯亂,困擾了我們好久,簡直是大坑,目前研究出暫時的解決方法是動態給所有用到圖片的元素加上

-webkit-transform : translate3d(0,0,0)

進行強制重繪,測試結果對於絕大部分出現問題的機子有效,但仍然有小部分機器還是會出問題,另一種方法是進行懶載入,但是這會降低開發效率,並且對使用background-image的元素比較難實現

*修正:

關於iPhone圖片亂串的問題,後來使用OS X的Safari調試後發現並不是渲染問題,而是請求回來的圖片本身就算錯的,最後通過修改從多個CDN地址取圖或者把圖分散到不同目錄下後問題解決,多次測試後也再沒有出現問題。

現在具體的原理還不知道,因為只有iOS會出現問題所以我們懷疑部分CDN的配置與iOS的請求機制不兼容,暫時可以歸位玄學問題XD


2.safari(包括OS X、iOS和Windows版)對transform-origin的Z軸判定和其它所有瀏覽器都不同,設置transform-origin的Z軸會直接產生translateZ的變換,十分不理解,暫無純css解法

3.Android調用重力感測器返回的數據和iOS和Windows Phone上的是相反的……

4.Android微信內置webview對meta viewport的支持有缺陷,當user-scalable=no時,設定width為固定數值(例如640)不會自動縮放,需要用js做一些處理
(新版微信已經修正了這個問題)

5.Android的各種瀏覽器都不支持同時播放多個音頻,並且通過js連續播放幾個音頻的時候會出現一些問題

暫時想到這麼多……


我來補充幾點吧。

  1. 圖片大小最好是標註的2倍,這樣可以保證在各類機型上的清晰
  2. 小圖片最好拼合起來做成雪碧圖,然後可以在TinyPNG – Compress PNG images while preserving transparency網站上壓縮後再Base64嵌入html或css中。移動端要儘可能減少請求。不過太大的圖片就不要base64了,性能會下降。一般以10k為界
  3. rem方案相當複雜,存在非常多的兼容問題,以至於阿里這邊還專門有一個Flexible庫來解決這一系列問題。但是兼容性問題解決後開發會變得非常暢快。
  4. 圖片比較多的頁面務必要做懶載入(也就是滾動到圖片的時候才載入)
  5. border-radius不要隨便亂用,在很多安卓機型上都會出現鋸齒,非常丑
  6. css動畫請使用transform,而非直接控制width,height,margin,否則會造成大量的計算,性能堪憂。transfrom會把元素獨立出來單獨計算的。
  7. 如果動畫比較多或者面積比較大,想提高性能的話可以用transform3D,就算不設置3d變換也會促使瀏覽器開啟硬體加速
  8. flex布局挺好,但有點兼容性問題,需要同時寫好幾個帶前綴的私有屬性才能保證大多數機型的適配。推薦使用autoprefixer,不過要記得自己定製兼容瀏覽器列表,不然會有很多-ms-,-o-這類的屬性,在移動端是沒有用的

想到了再補充吧。


iOS 彈出鍵盤時,viewport 高度並不會變,但是 Android 是變的。所以 iOS 上 fixed 在底部的元素顯示不出來。


1、做點擊跳轉,長按刪除功能的時候坑比較多:
(1)組合使用touchstart,touchmove,touchend,click事件;
(2)部分機型按到文字會彈出選擇,複製的選項,使用 onselectstart="return false;" 禁掉;
-- 之後才知道有很多移動端事件處理庫可以用,如 Hammer.JS - Hammer.js
2、1px邊框問題,可以延伸到很多知識,如物理像素,CSS像素,viewport, rem等等
再談mobile web retina 下 1px 邊框解決方案
移動前端開發之viewport的深入理解
從網易與淘寶的font-size思考前端設計稿與工作流
3、Hybird開發模式下,頁面跳轉及返回,因為涉及到H5頁面之間,H5與原生頁面,需要判定從H5還是從原生跳過來,返回鍵的處理不同。
還有就是用戶進入深層級的頁面然後返回,有時候需要特殊處理。
目前還沒有很好的解決方案,暫且採用url傳參的形式進行區分,做相應的處理;
4、相對於底部絕對定位的按鈕被鍵盤頂起來,用js定高

this.clientHeight = document.documentElement.clientHeight;
$("body").height(this.clientHeight);

5、一定要考慮文字過長的情況,要麼溢出隱藏,要麼換行不會影響布局。多使用一欄固定,另一欄(或多欄)自適應
6、IOS下和安卓對json對象的遍歷順序相反,如

var obj = {x: 1,y: 2},
str = "",
temp = "",
i = 0;
for(var item in obj){
temp = i === 0 ? "" : "";
i++;
str += temp + item + "=" + obj[item];
}
console.log(str);

安卓下輸出

x=1y=2

IOS下

y=2x=1


Safari Crashing http://www.digitaltrends.com/mobile/ipad-air-problems/19/#safari


年初用 fullpage.js 做了一個活動的宣傳頁面。裡面插入了大量 svg 代碼,並對部分的 path 本身添加了許多 css animation 和 transition 來做動畫效果。在針對 svg path 本身設定 transform 等動作時位置設置經常在不同的瀏覽器時表現完全不同,但因為匆忙上架所以我也就只對 android 上的chrome、iOS 的 safari 以及兩平台的微信內置瀏覽器做了一些調試,也算是基本能用。而 UC 等其他瀏覽器,因為這邊用的人少,我也就沒有花精力在它們上。

前期我是對每一個頁面單獨進行開發測試,但等到我全部完成了,開始一個個頁面滾動時,奇怪的問題出現了:iOS(準確來說是我的iPod touch 5)上,每當我翻到第四第五頁時,我所設定的css animation總是沒法生效,頁面也沒法滾動(大概因為 fullpage.js 用 transform 來實現滾動)。一開始以為是我的 css 語法有問題,但試著改了好幾遍都沒效果。而我在我的主力機(Android 平台)上測試多次,都正常運行。

後來我注意到一點,當頁面數少時,無論哪一個頁面都是能夠運行的。我嘗試將頁面改為每翻一頁都會把上上頁的元素從 DOM 移除,結果問題就完全解決了。我只能推測在(涉及 css 動畫的)頁面元素特別多時,Safari 因為內存或其他原因沒有足夠空間去運行新的動畫,導致了這個問題。至於它會不會在內存更大的(如 iPhone、iPad 等)設備上出現類似問題,時間倉促我也就沒有特別測試。

另外一個可能的原因是我用了 AngularJS 時加入比較多的 ng-animate 相關的組件(我一直用 angularjs 做網頁草稿……)來添加 css transition,是不是它的某些機制使得它在 iOS 上動畫終止,這點我也就沒有繼續試驗下去了。


千萬別在頁面底部放一個position為fixed的輸入框,iOS里會提不上來…


常見坑不表,只說 還沒正面解決的 ——

0. Android 4.x 一些版本 input file 被從底層閹割,文件選擇框 打不開也不報錯 —— http://www.zhihu.com/question/21452742

1. iScroll 5 官方示例 拖到本地開發環境就完全動不了,無論 Chrome 移動設備模擬器 還是 微信內置瀏覽器 —— 棄之不用,手寫下拉刷新……

2. ECharts 的雷達圖在 iOS WebView 中拖拽 容易使整個 ViewPort 高寬突破 meta 標籤的限制

3. Animate.css 中動作幅度較大的動畫在用 騰訊 X5 內核的 App 中卡頓明顯(鵝廠號稱的基於 Chrome 完整內核優化 哪兒去了?MIUI 原生瀏覽器 都超流暢)

4. WebKit 533-(微信、UC v9.8 開發者版)在遍歷 帶偽元素規則的 CSSStyleRule 對象時,會直接讓瀏覽器崩潰(下斷點走單步時基本沒事,一釋放斷點立馬崩潰,所以懷疑是棧溢出)—— 檢測到老內核 直接跳過那段代碼……(對老瀏覽器砍功能)

5. a 標籤 href 僅指向一個不存在的 hash,點擊回調中根據 hash 內容調用相應功能,並阻止默認行為 —— Android、iOS 上各種 WebKit 瀏覽器 都會清空歷史記錄(執行了 a 標籤的默認行為),導致單頁應用無法回退……(桌面端瀏覽器 均無此問題)

6. 微信 iOS 版 整頁切換到 動態生成的表單,其提交按鈕會自動點擊,導致空白表單提交 —— 自己給 iOS WebKit 補上砍掉的 HTML 5 表單元素驗證方法,提交前先驗證 HTML 代碼中的 required、pattern 屬性,否則阻止提交事件


(前端不棄,更新不止……)


剛好碰到一個,fixed頁腳定位,點擊輸入框彈出輸入法,這時候下滑動會把頁腳拉上來


剛碰到一個,iOS8 的 webview 載入網頁,不支持使用 createElement 創建 video 元素播放 hls 視頻流,然後動態指定 parent,會導致 app 崩潰。

並且,webview 視頻內嵌播放模式下點擊全屏按鈕會導致 app 崩潰。

以上問題原因不明,經驗證 iOS8 必現。


微信ios二維碼識別,不能放fix div里。safari translate3d(0,0,0). safari 有個tap event。safari 的a style cursor:pointer。基本上全是safari 的坑。 還有stupid safari mobile, IE 都沒問題的東西它出問題。


1.當 -webkit-overflow-scrolling 被設置為touch (iOS上momentum scrolling) 的時候,z-index會形成一個新的stacking context.
The stacking context

=11月3日更新
2.最近遇到一個巨坑,在ios9.0和9.1 的webview里,修改location.hash不會直接修改這個值,其中會有30ms左右的延遲。這個問題直接影響到了angular和backbone的navigation的實現。(angular已經發補丁了。)
How to fix window.location issue in iOS9 UIWebview

3.在ios webview下,不是所有的html元素都可以添加click事件,只有"clickable"的元素可以,如button,如果要加click事件到span,需要在span的html裡面加上onclick=""
Handling Events

4.ios 9.0 webview 有詭異的渲染bug。比如顏色閃爍,顏色渲染不完全等。解決方案看我stackoverflow上的這個答案
cordova - Why iOS9 WebView CSS Transform turns red element into blue ones?


移動版IE 。。。。。UC
坑過的自然懂。。。。。


parseint記得加第二個參數
5.0不能通過webview外部手勢觸發內部的media事件
不同的機型手勢觸發的數據信息的結構不一樣
太多了,想起再補充。


有一次邊走路邊讀開發文檔,沒想到前面的沙井沒井蓋!


強答一個
現在沒有深入研究了,14年做移動開發,國內某瀏覽器用js檢查有此API 但是方法是空
那時候手機瀏覽器有個跑分支持多少h5,實際上為了性能底層又不支持。


推薦閱讀:

<body/onload=alert(1)> 是什麼寫法?
一個前端菜鳥的艱苦尋找實習歷程?
CoffeeScript 需要怎樣進入瀏覽器?
給一個按鈕的 onclick 事件綁定兩個函數,應該如何控制觸發的先後順序?
一名合格的前端工程師的知識結構是怎樣的?

TAG:iOS | CSS | JavaScript | HTML5 | Android |