移動端(安卓、ios、微信端)的 兼容性問題


前言:這里移動端主要指 hybrid app 中的H5頁面。app 中頁面 樣式和功能 的需求會更精細一點。

1、適配: 手機端的尺寸多樣,3.5英寸的 iPhone4應該是最小的,只要考慮 兼容到iPhone4 就可以了。(iPhone4的用戶量現在也很少,有時只要 兼容到iPhone5 就可以了)

   哪怕有比這個尺寸小的,都不是多人使用的。可能是個位數,甚至是沒有。為數不多的幾款這樣的手機處理能力也很低下。       https://digi.tech.qq.com/a/20150312/011872.htm#p=1

   iPhone4 使用情況:iPhone4的系統, 現在的很多軟件都運行不了。  https://www.pc841.com/shouji/iPhone/19249.html(系統升級后也會有問題,大部分用戶是不會去升級的)  或  https://t.cj.sina.com.cn/articles/view/2972527830/b12d2cd60010084gl

  總結:

              rem + 媒體查詢 適配(rem基本可以適配大部分的移動端的適配,解決不了的使用媒體查詢基本可以解決),重點熟練下媒體查詢手機是用height還是device-height來查詢的。有的手機,下面有一條黑色的手機按鍵,此時的device-height有沒有包含這塊高度。
              注:不同手機寬度基本沒什么適配的,rem基本就解決了。主要是針對需要一屏顯示的頁面,高度差距太大,用rem基本沒什么效果。

2、 JS 呼起和隱藏鍵盤(默認是需要用戶點擊輸入框才能呼起): 智能機的鍵盤都是軟鍵盤。應用中有呼起鍵盤和隱藏鍵盤的需求。

   呼起鍵盤:進入搜索頁,要求鍵盤拉起。主要聚焦到input框就可以。(安卓上沒有問題,ios上無效)

    this.$refs.input.focus() // 在一個demo上安卓 和 ios都有效,但是正式項目中,ios中無效

   隱藏鍵盤:通過給input標簽,設置 readonly 屬性就可以使鍵盤收起來了。(安卓上沒有問題,ios上無效)

    <input type="text" ref="input" :readonly="readonly">

或,下面的方法 安卓 和 ios上都有效

      this.$refs.input.blur()

3、軟鍵盤呼起 引起的兼容性問題:

  a、 會使webview高度變小(這里就要求body最好設置一個最小的高度為沒有鍵盤時的高度),並且 fixed定位元素 跟着鍵盤上移 (安卓的問題):

     問題原因:

      安卓手機:同一個手機,H5頁面的 視口高度在鍵盤拉起和隱藏時,不一樣的。拉起時,鍵盤部分的高度變成原生的內容了,H5容器高度就變小了。(H5頁面本身的高度是不變的

           一般情況這個都不影響,但是如果底部有fixed定位的話。鍵盤拉起時,會把這塊內容也移上去的,需要做一個判斷進行隱藏(這個隱藏必須是針對對安卓機,ios機上不能隱藏。ios上也隱藏了,鍵盤)。

      ios手機:更不正常,鍵盤彈出不影響H5容器的大小變化的,即clientHeight的大小不變,但是卻出現了滾動(如果clientHeight同步變小,可以理解為變成了一個小屏的容器。但是ios這樣,只是把滾動條的范圍變小了;

                                 滾動條到底了,頁面的底部在鍵盤的上了。鍵盤遮擋的部分也是屬於clientHeight,這一部分的高度,憑空給H5頁面了)。總結起來就,ios中鍵盤彈起,會給H5頁面的高度增加了一個鍵盤的高度

          參考哪些高度發生的變化  https://blog.csdn.net/weixin_34163553/article/details/88686238

      個人看法:鍵盤彈出,可以這樣理解為h5的底板的大小就是webview的大小,包括鍵盤。底板上一張畫布,畫布高度可以被撐高,html、body等元素是固定在畫布上的。瀏覽器中頁面的滾動的跟着畫布滾動的。

         安卓上,畫布的最小高度是底板不包括鍵盤的高度ios上,畫布的最小高度是低板的高度加上鍵盤的高度。(css無非操作畫布的屬性)

    解決問題:

      頁面只能是一屏的:這個要考慮自適應。鍵盤呼起,webview的高度變小了。使用 absolute 定位,bottom 設置,定位參考的元素高度不能受webview高度的影響(給body設置一個最小高度,開始就通過js獲取);或者使用top設置高度。

               如果,要考慮所有手機中 底部的按鈕必須離底部相同的距離。這個可能就要使用js獲取 沒有鍵盤時屏幕的高度。然后把 定位參考 元素高度設置為這個值。

      頁面可以滾動:這個比較簡單,沒有鍵盤時,頁面高度已經 大於 容器的高度了。呼起鍵盤后還是滾動的。沒有任何的問題。  

  b、軟件盤喚起,在表單 外滑動,軟鍵盤不關閉,點擊才會關閉(這點表現,兩者是一樣的,沒有兼容性問題,記錄下這個特性)。

  c、軟件盤的關閉方法,表單失去焦點 / 軟件盤上的關閉按鈕 (這點表現,兩者是一樣的,沒有兼容性問題,記錄下這個特性

  d、點擊軟鍵盤上的關閉按鈕、安卓手機不會觸發 表單的  blur 事件,ios可以。(安卓的問題)

    需要  軟件盤關閉時 執行代碼,在安卓上就需要做兼容處理。(解決安卓的一些兼容性問題,必須要在軟鍵盤關閉時執行。如鍵盤拉起時,會把底部fixed元素移上去的,需要做一個判斷進行隱藏;關閉軟鍵盤時,再顯示)

  e、軟鍵盤喚起時fixed 元素失效(ios的問題):如下說明

4、 軟鍵盤呼起時fixed失效(fixed+input,ios的問題):(有一個inobounce插件,可以直接解決這個問題。功能上相當於使得畫布的高度,始終等於鍵盤上面到頂部的高度。不管鍵盤有沒有出來都這樣。有時間可以看下源碼)

  a、頂部 fixed元素,input框在頂部:點擊這個input框,fixed雖然失效了,但是頁面不會滾動。fiexd元素會滾動是因為軟鍵盤的彈出,fixed失效了(或變成了absolute),只要input失去焦點時,立刻把鍵盤關閉,fixed元素就沒有滾動的機會。

    這樣就可以解決fixed無效的問題了。

    中間部分有滾動部分的解決方案,有效 https://www.iteye.com/blog/570109268-2406086(解決了中間滾動部分的高度,不會引起畫布的滾動。畫布的滾動,還是會使fixed滾動,這個解決方法就是上面說的失去焦點,隱藏鍵盤)

  b、底部 fixed元素,input框在底部:這個input輸入框,點擊這個輸入框,頁面都會向上滾動的。input框始終在鍵盤上面,鍵盤關閉,滾上去的頁面也不會滾下來。

    這個 當表單失去焦點時(或觸發鍵盤隱藏事件時),讓頁面滾動到之前的位置就可以解決:

   document.documentElement.scrollTop = 100; // 這個值是彈出鍵盤前的位置

  inobounce  禁止IOS H5的滑動回彈 :https://blog.csdn.net/weixin_30610755/article/details/95260237

5、解決頁面,返回時重復的問題 (重要,app中返回是經常會用到的,所以瀏覽器歷史記錄需要頁面控制下。頁面前進或回退時,url只是參數的改變,頁面是不刷新的)

   A(列表頁) =》 B(詳情頁,B中有跳到A頁面的按鈕):列表A1 =》 B 點擊跳到A的按鈕 =》 

     列表A2  =》B。這個時候回退時,B=》A=》B=>A 會出現不斷重復的問題

  解決方案:使用vue路由的 vm.$router.replace() 方法跳轉,或 原生的 location.replace(URL) 

6、input中占位文字,無法上下居中對齊(應該是字體小於12px,引起的問題)。

7、ios監聽軟鍵盤確認按鈕:會無效(那個 確認 按鈕會變化 為換行 按鈕,換行時,監聽key=13是對的。變成確認時,監聽不了key=13的這個鍵。【猜測可能同一個鍵,確認的鍵盤碼不是13】)

   解決辦法: type="search"  的輸入控件,會使改變軟鍵盤確認按鈕的文字變成搜索(且鍵盤碼都是13)。https://blog.csdn.net/sinat_24070543/article/details/53423274 

<form action=""> // form 標簽必須加
   <input v-model="wordName" type="search" placeholder="輸入垃圾名稱搜一搜" @input="inputText" ref="input"/>
</form>

 這個方法可以不用監聽key=13事件,直接監聽form的 submit 事件同樣可以監聽 確認按鈕。

 (項目中是 在 搜索框 右邊加一個 搜索按鈕,不使用軟鍵盤上的確認按鈕)

  另:type=search表單,輸入文字后,右邊會有一個刪除文字按鈕的。解決方案:https://www.cnblogs.com/xiaoshen666/p/10772858.html

input[type="search"]::-webkit-search-cancel-button{
    -webkit-appearance: none;
}

8、小高度標簽內 單行文本 垂直居中 偏上的解決方案(安卓設備上):https://blog.csdn.net/zhanghuanhuan1/article/details/80339610  或  https://blog.csdn.net/liming911911/article/details/75389188(推薦)

  原因(個人猜測):移動端是支持12px以下的字體的。安卓上小於12px的字體,字體會溢出標簽一點。親測,如下圖,設置了居中的樣式,字體設置為10px,字體溢出他的包含標簽sapn。即,

             瀏覽器12px以下的字體 以12px顯示;移動端小於12px的字體,也可以正常顯示,但是排版有點小問題(會上移)。

                    

 常規的居中方案都沒有用的,使用scale可以近似解決,但是不夠完美。目前沒有其他的可行方法。或者使用媒體查詢小於12px的尺寸,就以12px顯示。折騰了好久,找不到好的辦法

9、ios上vue框架中返回 keep-alive 的頁面(這個頁面比較長,有滾動。滾到頂部,進入下一個頁面),會出現白屏(被什么東西遮擋住了)。手輕輕滑動下,遮擋層就消失了。

  原因及解決方法:https://blog.csdn.net/m0_38069630/article/details/80573283 (公司的項目中因為是多人開發,不好動html, body的屬性。所以沒用這個解決方案,只是不用 keep-alive 了

10、ios中 h5頁面 輸入框點擊空白處不會失去焦點 軟鍵盤不會收起(重要):

  解決方案:https://www.cnblogs.com/gd-dql/p/7476330.html(親測有效,里面使用touchend觸發,改成touchstart更好。有時間整理下,把里面的定時去掉)

11、ios-H5 中,不過頁面的高度是多少(html,body設置為50px,只有一個input標簽),只要鍵盤彈出,頁面就一定會滾動 。通過上面的方法,input失去焦點馬上隱藏鍵盤。這樣活動的時候鍵盤隱藏,頁面就不會滾動了。

  但是,在input內部滑動,還是會帶動頁面滾動的,給input標簽添加一個touchmove阻止默認事件。就完美了

document.getElementById('input').addEventListener("touchmove",function(event){
    event.preventDefault()
},false)

  (直接讓頁面不滾動,暫時沒有找到解決方案,因為html,body的高度根本沒有超出鍵盤的范圍。我想應該是有直接的解決辦法的,百度H5頁面,不知道是怎么解決的,有時間研究下)

12、禁止 ios 頁面上下滾動回彈(橡皮筋效果):沒有橡皮筋效果,就不會出現fixed失效的問題。

   解決方案1、使用 inobounce.js 插件(親測有效)。但是 整個頁面都不能滑動了,有溢出的屏幕的元素也不能滑動的。

       如果有需要滑動的元素,需要設置一個height或max-height,還有overflow: auto; -webkit-overflow-scrolling: touch;     https://blog.csdn.net/weixin_30610755/article/details/95260237

  解決方案2、參考 https://blog.csdn.net/m0_37068028/article/details/80183781 (親測,兩個方案都有效)

  說明:通過閱讀 inobounce.js 的源碼(源碼代碼量很少),發現 原理就是使用window代理屏幕上的 touchmove 事件( window.addEventListener)。判斷當前觸發的對象是非滾動區域,則阻止事件的默認行為;滾動區域,不阻止事件。

      具體實現,插件中考慮的比較全面,比較復雜。直接使用插件是最方便的。

13、js沒有監聽 手機端軟鍵盤 彈出 / 關閉事件,可以封裝一個這樣的函數。https://www.cnblogs.com/wind-wang/p/10711259.html

  安卓 和 ios 對軟鍵盤關閉的行為是不一樣的。安卓中 軟鍵盤關閉,webview高度變化(blur事件不一定觸發);ios中 軟鍵盤關閉,觸發 blur事件【或focusout】(webview高度沒有變化)。

14、 fixed的遮罩層上面可以滾動,下面內容禁止滾動。 (有時間再單獨研究下,fiexd遮罩層上的事件,如點擊,滾動對下面的內容的影響

    解決方案:移動端開發,body內的元素,最外層的標簽要設置一個高度(一般是容器的高度100vh),溢出屬性設置滾動。不要讓body的高度超過100vh了,不然 fixed的遮罩層上面滾動,下面的內容一會滾動。處理起來比較麻煩。

    親測問題:在fixed層上使用vue的    @touchmove.prevent  阻止默認事件,結果上下兩層的滾動都禁止了; 使用  @touchmove.stop 阻止冒泡事件,結果無效。

    問題分析:

    a、body 的 高度超過 容器高度,body是比較特殊的標簽。fixe層的touchmove事件,會導致body滾動。

    b、非 body的標簽,如 div標簽是一個溢出滾動的標簽,其內的一個標簽作為 fixed遮罩層,則遮罩層內的內容滾動,不會觸發這個div標簽的高度。(個人猜測,遮罩層雖然在div標簽內,但是已經脫離標准文檔流,事件上於div已經沒有關系)

       c、body是比較特殊的 標簽,fixed遮罩層內 的 touchmove 還是會到 body上的。

15、 IOS獲取短信驗證碼--自動填充被復制兩遍問題:    參考鏈接

   說明:測試測出這個bug,自己測試一直沒復現出來。可能觸發機制不是很准確。

16、video標簽,在安卓手機 不能自動播放: https://blog.csdn.net/weixin_34037173/article/details/88718114 

         在安卓的容器(webview)中,視頻播放需要點擊兩次,即播放-暫停-播放,才能開始播放。(暫時沒有找到解決方案)

17、移動端 input[type=file] 標簽 本地文件、拍照、錄像 上傳的兼容性問題: 參考自己的另外一篇博客,https://www.cnblogs.com/wfblog/p/12887737.html

18、安卓中video播放完 視頻 后,會自動跳到,視屏廣告的內容上去。https://blog.csdn.net/Dream_Weave/article/details/103095517

 

 

 

總結:安卓和ios的兼容性,主要的問題,還是軟件鍵盤引起的。所以兩者關於軟鍵盤的處理一定要讓他們盡可能的保持一致。如下要做到一致:

  a、輸入框,聚焦時彈出軟件盤。失去焦點時,隱藏軟件盤(ios需要處理的)。

  b、ios 的 橡皮筋效果 一定要禁掉(使用 inobounce 插件)。

  c、ios 和 安卓 兩者 對軟鍵盤關閉 的判斷的邏輯不同(軟鍵盤關閉時,執行代碼這個功能是一定會用到的)。現在的手機 不是ios就是安卓手機,可以把這兩段代碼封裝在一個方法里,變成一個軟鍵盤關閉的事件(實際開發中,一般只是對一種情況做出處理)。

        if(isIOS){ // 在 ios 中執行下面監聽事件,捕獲 軟鍵盤關閉事件。(isIOS 通過獲取 navigator.userAgent就可以判斷
            window.addEventListener('focusin', () => {  // 鍵盤彈出事件處理
                alert("iphone 鍵盤彈出事件處理")
            });
            window.addEventListener('focusout', () => {  // 鍵盤收起事件處理
                alert("iphone 鍵盤收起事件處理")
            });
        }
        if(isAndroid){ // 在 android 中執行下面監聽事件,捕獲 軟鍵盤關閉事件
            const innerHeight = window.innerHeight;
            window.addEventListener('resize', () => {
                const newInnerHeight = window.innerHeight;
                if (innerHeight > newInnerHeight) {  // 鍵盤彈出事件處理
                    alert("android 鍵盤彈窗事件");
                } else {  // 鍵盤收起事件處理
                    alert("android 鍵盤收起事件處理")
                }
            });
        }

 感悟:1、如果不用 輸入框,基本沒有什么兼容性問題。css的兼容性問題也基本沒有,就幾個默認樣式的區別;沒有軟鍵盤,ios回彈效果也沒什么影響,可以不做處理。

    2、上面講的安卓和ios上的兼容性問題,都是webview內核的兼容性問題。hybrid-app中SDK方法也會有兼容問題的,這種bug完全就是安卓和ios軟件開發者沒有(或無法)統一引起的。一般安卓和ios是不同的人開發的。

     同樣的微信軟件,在ios上和安卓上清除緩存的功能都是不一樣的。微信JS-SDK,在處理分享鏈接鏈接也是有差異。自己公司開發是“杭州辦事服務”APP,JS調用原生的語音功能也存在兼容性問題。


 文章閱讀

1、移動端項目實戰心得: 參考鏈接


 移動端事件: https://www.jianshu.com/p/201518903985(原生的沒有 tap 和 swipe 事件)

1、touch事件:

  touchstart:手指觸摸到屏幕會觸發

  touchmove:當手指在屏幕上移動時,會觸發

  touchend:當手指離開屏幕時,會觸發。

  touchcancel:可由系統進行的觸發,比如手指觸摸屏幕的時候,突然alert了一下,或者系統中其他打斷了touch的行為,則可以觸發該事件。(在瀏覽器的模擬器中觸發touchcancel事件,Alt+Tab鍵)

     注意:使用 touchend 事件時,一定要考慮touchcancel事件。比如,語音功能。按下說話,突然彈出 語音權限未開。這個時候手指拿開就不會觸發touchend事件了,touch事件被打斷了,屏幕上一直是touchstart的狀態。

        必須加上 touchcancel 事件,補充 手指拿開后的頁面狀態。


移動端各種高度:(在pc上,瀏覽的高度對用戶基本什么問題。但是在移動端瀏覽的各種高度問題。比如webview的高度,是否包含軟鍵盤,不同的系統有差異性。微信的H5頁面,底部有左右前進按鈕欄,webview的高度是否又包含這個)

參考:https://segmentfault.com/a/1190000010443608 或 https://www.jianshu.com/p/27b68f780054?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1、window.outerHeight:【不常用】窗口的外部高度,包括所有界面元素(如工具欄/滾動條)。手機端,這個值和innerHeight一樣。

2、window.innerHeight:【一般】瀏覽器窗口高度(包括橫向滾動條的高度,沒有橫向滾動條,和documentElement.clientHeight是一樣的。https://www.cnblogs.com/suihang/p/11177093.html )。(ios中軟鍵盤彈出時,有兩個值)

3、body.offsetHeight:【不用】網頁可見區域高(不確定具體的含義,值和scrollHeight一樣。)。

4、body.clientHeight(兼容問題):瀏覽器窗口高度(不包括橫向滾動條)。(不同瀏覽器表達方式不一樣,谷歌中他的值無效。使用 documentElement.clientHeight【常用】)

5、body.scrollHeight(兼容問題):網頁正文 全文高。可以理解為畫布的高度。(谷歌中他的值表示body的高度,使用 documentElement.scrollHeight【常用】。https://www.cnblogs.com/nanshanlaoyao/p/5964730.html

6、body.scrollTop(兼容問題):滾動條在Y軸上的滾動距離,即文檔上邊出去的高度。(谷歌、火狐上都為0,使用 documentElement.scrollTop【常用 。https://www.jianshu.com/p/4c37a2a56586

   兼容性解決方案:https://www.cnblogs.com/winyh/p/6715010.html

7、window.screenTop:【不常用】窗口相對於屏幕的Y坐標。即瀏覽器頂部距離顯示器頂部的距離。https://www.w3cschool.cn/jsref/prop-win-screenleft.html

8、screen.height:【不常用】屏幕分辨率的高,即顯示器的高度。

9、screen.availHeight:【不常用】顯示器除去底部任務欄后的高度。https://www.w3school.com.cn/jsref/prop_screen_availheight.asp

各種高度 鍵盤沒有彈出(安卓) 鍵盤彈出后(安卓)   鍵盤沒有彈出(ios) 鍵盤彈出后(ios)   微信網頁底部左右箭頭欄隱藏(ios) 微信網頁底部左右箭頭欄顯示(ios)
window.outerHeight 647 380    603  603      
window.innerHeight 647  380    603  603,293(滾動到底部)       
body.offsetHeight 771  771    793  793       
body.clientHeight 771  771   793  793       
body.scrollHeight 795  795   817  817       
body.scrollTop 68         
window.screenTop        
screen.height 720  720    667  667       
screen.availHeight 720  720    667  667       

 


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM