移動端與pc端的區別 及 ios的 兼容性問題

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

一、適配: 手機端的尺寸多樣,3.5英寸的 iPhone4應該是最小的,只要考慮 兼容到iPhone4 就能夠了。(iPhone4的用戶量如今也不多,有時只要 兼容到iPhone5 就能夠了)html

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

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

  總結:ios

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

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

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

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

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

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

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

this.$refs.input.blur()

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

  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的問題):以下說明

四、 軟鍵盤呼起時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

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

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

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

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

六、input中佔位文字,沒法上下居中對齊(應該是字體小於12px,引發的問題)。

七、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; }

八、小高度標籤內 單行文本 垂直居中 偏上的解決方案(安卓設備上):https://blog.csdn.net/zhanghuanhuan1/article/details/80339610  或  http://www.javashuo.com/article/p-tmcpygqp-mq.html(推薦)

  緣由(我的猜想):移動端是支持12px如下的字體的。安卓上小於12px的字體,字體會溢出標籤一點。親測,以下圖,設置了居中的樣式,字體設置爲10px,字體溢出他的包含標籤sapn。即,

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

                    

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

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

  緣由及解決方法:http://www.javashuo.com/article/p-mqsdltvc-nm.html (公司的項目中由於是多人開發,很差動html, body的屬性。因此沒用這個解決方案,只是不用 keep-alive 了

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

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

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

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

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

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

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

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

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

  解決方案二、參考 http://www.javashuo.com/article/p-zkwhbnsh-ma.html (親測,兩個方案都有效)

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

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

1三、js沒有監聽 手機端軟鍵盤 彈出 / 關閉事件,能夠封裝一個這樣的函數。http://www.javashuo.com/article/p-atnyvqzh-kx.html

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

1四、 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上的。

 

 

總結:安卓和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 鍵盤收起事件處理") } }); }

 感悟:一、若是不用 輸入框,基本沒有什麼兼容性問題。css的兼容性問題也基本沒有,就幾個默認樣式的區別;沒有軟鍵盤,ios回彈效果也沒什麼影響,能夠不作處理。

    二、上面講的安卓和ios上的兼容性問題,都是webview內核的兼容性問題。hybrid-app中SDK方法也會有兼容問題的,這種bug徹底就是安卓和ios軟件開發者沒有(或沒法)統一引發的。通常安卓和ios是不一樣的人開發的。

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


 文章閱讀

一、移動端項目實戰心得: 參考連接


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

一、touch事件:

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

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

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

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

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

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


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

參考:http://www.javashuo.com/article/p-kyqdyljr-cw.html 或 https://www.jianshu.com/p/27b68f780054?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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

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

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

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

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

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

   兼容性解決方案:http://www.javashuo.com/article/p-vocykzuq-s.html

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

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

九、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 
相關文章
相關標籤/搜索