ios和android適配問題總結


_________________________________________________________________________________javascript

相關知識點

移動端、 適配(兼容)、 ios點擊事件300ms延遲、 點擊穿透、 定位失效......css

問題&解決方案

  • 手機瀏覽器獨有的三個事件?
onTouchmove,ontouchend,ontouchstart,ontouchcancel
  • 爲何要用Zepto?
jquery適用於PC端桌面環境,桌面環境更加複雜,jquery須要考慮的因素很是多,尤爲表如今兼容性上面,相對於PC端,移動端的發雜都遠不及PC端,手機上的帶寬永遠比不上pc端。pc端下載jquery到本地只須要1~3秒(90+K),可是移動端就慢了不少,2G網絡下你會看到一大片空白網頁在加載,相信用戶第二次就沒打開的慾望了。zepto解決了這個問題,只有不到10K的大小,2G網絡環境下也毫無壓力,表現不遜色於jquery。因此移動端開發首選框架,我的推薦zepto.js。
  • IOS移動端click事件300ms的延遲響應
移動設備上的web網頁是有300ms延遲的,玩玩會形成按鈕點擊延遲甚至是點擊失效。這是因爲區分單擊事件和雙擊屏幕縮放的歷史緣由形成的,
2007年蘋果發佈首款iphone上IOS系統搭載的safari爲了將適用於PC端上大屏幕的網頁能比較好的展現在手機端上,使用了雙擊縮放(double tap to zoom)的方案,好比你在手機上用瀏覽器打開一個PC上的網頁,你可能在看到頁面內容雖然能夠撐滿整個屏幕,可是字體、圖片都很小看不清,此時能夠快速雙擊屏幕上的某一部分,你就能看清該部分放大後的內容,再次雙擊後能回到原始狀態。
雙擊縮放是指用手指在屏幕上快速點擊兩次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。
緣由就出在瀏覽器須要如何判斷快速點擊上,當用戶在屏幕上單擊某一個元素時候,例如跳轉連接<a href="#"></a>,此處瀏覽器會先捕獲該次單擊,但瀏覽器不能決定用戶是單純要點擊連接仍是要雙擊該部分區域進行縮放操做,因此,捕獲第一次單擊後,瀏覽器會先Hold一段時間t,若是在t時間區間裏用戶未進行下一次點擊,則瀏覽器會作單擊跳轉連接的處理,若是t時間裏用戶進行了第二次單擊操做,則瀏覽器會禁止跳轉,轉而進行對該部分區域頁面的縮放操做。那麼這個時間區間t有多少呢?在IOS safari下,大概爲300毫秒。這就是延遲的由來。形成的後果用戶純粹單擊頁面,頁面須要過一段時間才響應,給用戶慢體驗感受,對於web開發者來講是,頁面js捕獲click事件的回調函數處理,須要300ms後才生效,也就間接致使影響其餘業務邏輯的處理。
解決方案:
fastclick能夠解決在手機上點擊事件的300ms延遲
zepto的touch模塊,tap事件也是爲了解決在click的延遲問題
觸摸事件的響應順序爲 touchstart --> touchmove --> touchend --> click,也能夠經過綁定ontouchstart事件,加快對事件的響應,解決300ms延遲問題
  • 一些狀況下對非可點擊元素如(label,span)監聽click事件,ios下不會觸發
解決方案:css增長cursor:pointer;
  • 三星手機遮罩層下的input、select、a等元素能夠被點擊和focus(點擊穿透)
問題發現於三星手機,這個在特定需求下才會有,所以若是沒有相似問題的能夠不看。首先需求是浮層操做,在三星上被遮罩的元素依然能夠獲取focus、click、change),有兩種解決方案:
1.是經過層顯示之後加入對應的class名控制,截斷顯示層下方可獲取焦點元素的事件獲取
2.是經過將可獲取焦點元素加入的disabled屬性,也能夠利用屬性加dom鎖定的方式(disabled的一種變換方式)
  • 安卓瀏覽器看背景圖片,有些設備會模糊。
//用同等比例的圖片在PC機上很清楚,可是手機上很模糊,緣由是什麼呢?
通過研究,是devicePixelRatio做怪,由於手機分辨率過小,若是按照分辨率來顯示網頁,這樣字會很是小,因此蘋果當初就把iPhone 4的960*640分辨率,在網頁裏只顯示了480*320,這樣devicePixelRatio=2。如今android比較亂,有1.5的,有2的也有3的。
想讓圖片在手機裏顯示更爲清晰,必須使用2x的背景圖來代替img標籤(通常狀況都是用2倍)。例如一個div的寬高是100*100,背景圖必須得200*200,而後background-size:contain;,這樣顯示出來的圖片就比較清晰了。
//代碼能夠以下:
background:url(../images/icon/all.png)  no-repeat center center;
-webkit-background-size:50px 50px;
background-size: 50px 50px;
display:inline-block; 
width:100%; 
height:50px;
  • h5頁面有個很蛋疼的問題就是,當輸入框在最底部,點擊軟鍵盤後輸入框會被遮擋。
//可採用以下方式解決
var oHeight = $(document).height(); //瀏覽器當前的高度
 $(window).resize(function(){ 
      if($(document).height() < oHeight){ 
            $("#footer").css("position","static"); 
      }else{ 
            $("#footer").css("position","absolute");
      } 
});

關於Web移動端Fixed佈局的解決方案,這篇文章也不錯 http://efe.baidu.com/blog/mobile-fixed-layout/html

  • 不讓 Android 手機識別郵箱
<meta content="email=no" name="format-detection" />
  • 禁止 iOS 識別長串數字爲電話
<meta content="telephone=no" name="format-detection" />
  • 禁止 iOS 彈出各類操做窗口
-webkit-touch-callout:none
  • 消除 transition 閃屏
-webkit-transform-style: preserve-3d; /*設置內嵌的元素在 3D 空間如何呈現:保留 3D*/
-webkit-backface-visibility: hidden; /*(設置進行轉換的元素的背面在面對用戶時是否可見:隱藏)*/
  • iOS 系統中文輸入法輸入英文時,字母之間可能會出現一個六分之一空格
能夠經過正則去掉     
 this.value = this.value.replace(/\u2006/g, '');
  • 禁止ios和android用戶選中文字
-webkit-user-select:none
  • 在ios和andriod中,audio元素和video元素沒法自動播放
//解決方案:觸屏即播
$('html').one('touchstart',function(){ audio.play()})
  • ios下取消input在輸入的時候英文首字母的默認大寫
<input autocapitalize="off" autocorrect="off" />
  • android下取消輸入語音按鈕
input::-webkit-input-speech-button {display: none}
  • CSS動畫頁面閃白,動畫卡頓
//解決方法:
1.儘量地使用合成屬性transform和opacity來設計CSS3動畫,不使用position的left和top來定位
2.開啓硬件加速
  -webkit-transform: translate3d(0, 0, 0);
     -moz-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
          transform: translate3d(0, 0, 0);
  • fixed定位缺陷
ios下fixed元素容易定位出錯,軟鍵盤彈出時,影響fixed元素定位
android下fixed表現要比iOS更好,軟鍵盤彈出時,不會影響fixed元素定位
ios4下不支持position:fixed
解決方案: 可用iScroll插件解決這個問題
  • 阻止旋轉屏幕時自動調整字體大小
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {-webkit-text-size-adjust:none;}
  • Input 的placeholder會出現文本位置偏上的狀況
input 的placeholder會出現文本位置偏上的狀況:
PC端設置line-height等於height可以對齊,而移動端仍然是偏上,解決是設置line-height:normal;
  • 往返緩存問題
點擊瀏覽器的回退,有時候不會自動執行js,特別是在mobile safari中。這與*往返緩存(bfcache)*有關係。
解決方法 :window.onunload = function(){};
  • calc的兼容性處理
CSS3中的calc變量在iOS6瀏覽器中必須加-webkit-前綴,目前的FF瀏覽器已經無需-moz-前綴。
Android瀏覽器目前仍然不支持calc,因此要在以前增長一個保守尺寸:
div { width: 95%; width: -webkit-calc(100% - 50px); width: calc(100% - 50px); }
  • iOS6下僞類:hover
    除了<a>以外的元素無效; 在Android下則有效。相似 div#topFloatBar_l:hover #topFloatBar_menu { display:block; } 這樣的導航顯示在iOS6點擊沒有點擊效果,只能經過增長點擊偵聽器給元素增減class來控制子元素。  
  • 在移動端修改難看的點擊的高亮效果,iOS和安卓下都有效:
     ```
    *{-webkit-tap-highlight-color:rgba(0,0,0,0);}
    不過這個方法在如今的安卓瀏覽器下,只能去掉那個橙色的背景色,點擊產生的高亮邊框仍是沒有去掉,有待解決!
- 一個CSS3的屬性,加上後,所關聯的元素的事件監聽都會失效,等於讓元素變得「看得見,點不着」。IE到11纔開始支持,其餘瀏覽器的當前版本基本都支持。

pointer-events: none;html5

詳細介紹見這裏:[https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events](https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events)
- Zepto點透的解決方案

zepto的tap是經過兼聽綁定在document上的touch事件來完成tap事件的模擬的,及tap事件是冒泡到document上觸發的,在點擊完成時的tap事件(touchstart\touchend)須要冒泡到document上纔會觸發,而在冒泡到document以前,用戶手的接觸屏幕(touchstart)和離開屏幕(touchend)是會觸發click事件的,由於click事件有延遲觸發(這就是爲何移動端不用click而用tap的緣由)(大概是300ms,爲了實現safari的雙擊事件的設計),因此在執行完tap事件以後,彈出來的選擇組件立刻就隱藏了,此時click事件還在延遲的300ms之中,當300ms到來的時候,click到的其實不是完成而是**隱藏以後的下方的元素,若是正下方的元素綁定的有click事件此時便會觸發,若是沒有綁定click事件的話就當沒click,可是正下方的是input輸入框(或者select選擇框或者單選複選框),點擊默認聚焦而彈出輸入鍵盤,也就出現了上面的點透現象。
//(1)引入fastclick.js,在頁面中加入以下js代碼
window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );
//(2)或者有zepto或者jQuery的js裏面加上
$(function() {
FastClick.attach(document.body);
});
//(3)固然require的話就這樣:
var FastClick = require('fastclick');
FastClick.attach(document.body, options);
//(4)用touchend代替tap事件並阻止掉touchend的默認行爲preventDefault()
$("#cbFinish").on("touchend", function (event) {
//不少處理好比隱藏什麼的
event.preventDefault();
});
//(5)延遲必定的時間(300ms+)來處理事件
\(("#cbFinish").on("tap", function (event) { setTimeout(function(){ //不少處理好比隱藏什麼的 },320); }); ``` - 圖片加載 若您遇到圖片加載很慢的問題,對這種狀況,手機開發通常用canvas方法加載: 具體的canvas API 參見:http://javascript.ruanyifeng.com/htmlapi/canvas.html ``` 下面舉例說明一個canvas的例子: <li><canvas></canvas></li> js動態加載圖片和li 總共舉例17張圖片! vartotal=17; varzWin=\)(window);
varrender=function(){
varpadding=2;
varwinWidth=zWin.width();
varpicWidth=Math.floor((winWidth-padding*3)/4);
vartmpl ='';
for(vari=1;i<=totla;i++){
varp=padding;
varimgSrc='img/'+i+'.jpg';
if(i%4==1){
p=0;
}
tmpl +='java

  • ';
    varimageObj = newImage();
    imageObj.index = i;
    imageObj.onload = function(){
    varcvs =$('#cvs_'+this.index)[0].getContext('2d');
    cvs.width = this.width;
    cvs.height=this.height;
    cvs.drawImage(this,0,0);
    }
    imageObj.src=imgSrc;
    }
    }
    render();

    - 防止手機中網頁放大和縮小
    - apple-mobile-web-app-capable

    apple-mobile-web-app-capable是設置Web應用是否以全屏模式運行。
    語法:
    說明:若是content設置爲yes,Web應用會以全屏模式運行,反之,則不會。
    content的默認值是no,表示正常顯示。你能夠經過只讀屬性window.navigator.standalone來肯定網頁是否以全屏模式顯示。jquery

    - html5調用安卓或者ios的撥號功能

    html5提供了自動調用撥號的標籤,只要在a標籤的href中添加tel:就能夠了。
    以下:
    <ahref="tel:4008106999,1034">400-810-6999 轉 1034
    撥打手機直接以下:
    點擊撥打15677776767android

    - html5GPS定位功能  具體請看:http://www.jb51.net/post/html5_GPS_getCurrentPosition
    - 上下拉動滾動條時卡頓、慢

    body {
    -webkit-overflow-scrolling:touch;
    overflow-scrolling: touch;
    }ios

    #####Android3+和iOS5+支持CSS3的新屬性爲overflow-scrolling
    
    - 禁止複製、選中文本

    Element {-webkit-user-select:none;
    -moz-user-select:none;
    -khtml-user-select:none;
    user-select:none;
    }css3

    - iphone及ipad下輸入框默認內陰影

    Element{
    -webkit-appearance:none;
    }web

    - 1三、ios和android下觸摸元素時出現半透明灰色遮罩

    Element {
    -webkit-tap-highlight-color:rgba(255,255,255,0)
    }
    設置alpha值爲0就能夠去除半透明灰色遮罩,備註:transparent的屬性值在android下無效。

    一篇文章有詳細介紹,地址:http://www.jb51.net/post/phone_web_ysk
    - active兼容處理 即 僞類 :active 失效

    方法一:body添加ontouchstart

    方法二:js給 document 綁定 touchstart 或 touchend 事件

    bar

    - 動畫定義3D啓用硬件加速

    Element {
    -webkit-transform:translate3d(0,0,0)
    transform: translate3d(0,0,0);
    }
    注意:3D變形會消耗更多的內存與功耗

    - Retina屏的1px邊框

    Element{
    border-width:thin;
    }

    - webkit mask 兼容處理

    某些低端手機不支持css3 mask,能夠選擇性的降級處理。
    好比可使用js判斷來引用不一樣class:
    if('WebkitMask'indocument.documentElement.style){
    alert('支持mask');
    }else{
    alert('不支持mask');
    }

    - 圓角bug

    某些Android手機圓角失效
    解決方案:background-clip: padding-box;

    - 頂部狀態欄背景色

    說明:除非你先使用apple-mobile-web-app-capable指定全屏模式,不然這個meta標籤不會起任何做用。
    若是content設置爲default,則狀態欄正常顯示。
    若是設置爲blank,則狀態欄會有一個黑色的背景。
    若是設置爲blank-translucent,則狀態欄顯示爲黑色半透明。
    若是設置爲default或blank,則頁面顯示在狀態欄的下方,即狀態欄佔據上方部分,頁面佔據下方部分,兩者沒有遮擋對方或被遮擋。
    若是設置爲blank-translucent,則頁面會充滿屏幕,其中頁面頂部會被狀態欄遮蓋住(會覆蓋頁面20px高度,而iphone4和itouch4的Retina屏幕爲40px)。
    默認值是default。

    - 設置緩存

    手機頁面一般在第一次加載後會進行緩存,而後每次刷新會使用緩存而不是去從新向服務器發送請求。
    若是不但願使用緩存能夠設置no-cache。

    - 桌面圖標





    iOS下針對不一樣設備定義不一樣的桌面圖標。若是不定義則以當前屏幕截圖做爲圖標。
    上面的寫法可能你們會以爲會有默認光澤,下面這種設置方法能夠去掉光澤效果,還原設計圖的效果!

    圖片尺寸能夠設定爲5757(px)或者Retina能夠定爲114114(px),ipad尺寸爲72*72(px)

    - 啓動畫面


    iOS下頁面啓動加載時顯示的畫面圖片,避免加載時的白屏。
    能夠經過madia來指定不一樣的大小:













    - 瀏覽器私有及其它meta

    如下屬性在項目中沒有應用過,能夠寫一個demo測試如下!
    //QQ瀏覽器私有
    全屏模式

    強制豎屏

    強制橫屏

    應用模式

    //UC瀏覽器私有
    全屏模式

    強制豎屏

    強制橫屏

    應用模式

    //其它
    針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,好比黑莓

    微軟的老式瀏覽器

    windows phone 點擊無高光

    - IOS中input鍵盤事件keyup、keydown、keypress支持不是很好

    問題是這樣的,用input search作模糊搜索的時候,在鍵盤裏面輸入關鍵詞,會經過ajax後臺查詢,而後返回數據,而後再對返回的數據進行關鍵詞標紅。用input監聽鍵盤keyup事件,在安卓手機瀏覽器中是能夠的,可是在ios手機瀏覽器中變紅很慢,用輸入法輸入以後,並未馬上相應keyup事件,只有在經過刪除以後才能相應!
    解決辦法:
    能夠用html5的oninput事件去代替keyup


    而後就達到相似keyup的效果!

    - h5網站input 設置爲type=number的問題
    • h5網頁input 的type設置爲number通常會產生三個問題,一個問題是maxlength屬性很差用了。
      另一個是form提交的時候,默認給取整了。三是部分安卓手機出現樣式問題。
    //問題一解決,我目前用的是js。以下
    <input type="number"oninput="checkTextLength(this ,10)">
    functioncheckTextLength(obj, length) {  
          if(obj.value.length > length)  {     
            obj.value = obj.value.substr(0, length);  
          } 
    }
    //問題二,是由於form提交默認作了表單驗證,step默認是1,要設置step屬性,假如保留2位小數,寫法以下:
    <input type="number"step="0.01"/>
    關於step,我在這裏作簡單的介紹,input 中type=number,通常會自動生成一個上下箭頭,點擊上箭頭默認增長一個step,點擊下箭頭默認會減小一個step。number中默認step是1。也就是step=0.01,能夠容許輸入2位小數,而且點擊上下箭頭分別增長0.01和減小0.01。
    假如step和min一塊兒使用,那麼數值必須在min和max之間。
    看下面的例子:
    <input type="number"step="3.1"min="1"/>
    輸入框能夠輸入哪些數字?
    首先,最小值是1,那麼能夠輸入1.0,第二個是能夠輸入(1+3.1)那就是4.1,以此類推,每次點擊上下箭頭都會增長或者減小3.1,輸入其餘數字無效。這就是step的簡單介紹。
    //問題三,去除input默認樣式
    input[type=number] {
      -moz-appearance:textfield;
    }
    input[type=number]::-webkit-inner-spin-button,
    input[type=number]::-webkit-outer-spin-button {
      -webkit-appearance:none;
      margin:0;
    }
    • ios 設置input 按鈕樣式會被默認樣式覆蓋
    解決方式以下:
    input,
    textarea {
      border: 0; 
      -webkit-appearance: none; 
    }
    設置默認樣式爲none
    • select 下拉選擇設置右對齊
    設置以下:
    select option {
        direction: rtl;
    }
    • 經過transform進行skew變形,rotate旋轉會形成出現鋸齒現象
    能夠設置以下:
    -webkit-transform: rotate(-4deg) skew(10deg) translateZ(0);
     transform: rotate(-4deg) skew(10deg) translateZ(0);
     outline: 1px solid rgba(255,255,255,0)
    • 關於 iOS 與 OS X 端字體的優化(橫豎屏會出現字體加粗不一致等)
    iOS 瀏覽器橫屏時會重置字體大小,設置 text-size-adjust 爲 none 能夠解決 iOS 上的問題,
    但桌面版 Safari 的字體縮放功能會失效,所以最佳方案是將 text-size-adjust 爲 100% 。
    -webkit-text-size-adjust:100%;
    -ms-text-size-adjust:100%;
    text-size-adjust:100%;
    • 移動端 HTML5 audio autoplay 失效問題
    這個不是 BUG,因爲自動播放網頁中的音頻或視頻,會給用戶帶來一些困擾或者沒必要要的流量消耗,因此蘋果系統和安卓系統一般都會禁止自動播放和使用 JS 的觸發播放,必須由用戶來觸發才能夠播放。
    解決方法思路:先經過用戶 touchstart 觸碰,觸發播放並暫停(音頻開始加載,後面用 JS 再操做就沒問題了)。
    document.addEventListener('touchstart',function() {
      document.getElementsByTagName('audio')[0].play();
      document.getElementsByTagName('audio')[0].pause();
    });
    • 移動端 HTML5 input date 不支持 placeholder 問題
    這個我感受沒有什麼好的解決方案,用以下方法
    <input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')"  id="date">
    • 部分機型存在type爲search的input,自帶close按鈕樣式修改方法
    有些機型的搜索input控件會自帶close按鈕(一個僞元素),而一般爲了兼容全部瀏覽器,咱們會本身實現一個,此時去掉原生close按鈕的方法爲:
    #Search::-webkit-search-cancel-button{
      display:none; 
    }
    若是想使用原生close按鈕,又想使其符合設計風格,能夠對這個僞元素的樣式進行修改。
    • 喚起select的option展開
    //zepto方式:
    $(sltElement).trigger("mousedown");
    //原生js方式:
    functionshowDropdown(sltElement) {
      varevent;
      event = document.createEvent('MouseEvents');
      event.initMouseEvent('mousedown',true,true, window);
      sltElement.dispatchEvent(event);
    };

    以上全部資料蒐集整理自網絡,若有不對的地方但願及時告知,歡迎你們批評指正,謝謝!

    相關文章
    相關標籤/搜索