總結在移動端碰到的坑

1、安卓設備的select options的坑,儘可能使用各瀏覽器內核都支持的apicss

 在添加 OPTION 元素時html

  • 若是須要向指定索引前插入 OPTION,可使用 options.add(option, index);
  • 若是須要向 SELECT 尾部添加 OPTION,可使用 options.add(option);
  • 若是須要向指定索引處添加(或更改) OPTION,可使用 options[index] = option。    

 在刪除 OPTION 元素時node

  • 若是想刪除指定索引處的 OPTION 元素,可使用 select.remove(index) 或 options[index] = null;
  • 若是想刪除某個指定的 OPTION 元素,可使用 select.remove(option);
  • 若是想刪除 SELECT 中全部 OPTION,可使用 select.length = 0 或 options.length = 0。

2、移動端click事件300ms延遲android

 click事件,在移動端,會通過300ms的延遲後才觸發。緣由是,移動瀏覽器提供一個特殊的功能:雙擊(double tap)放大,用戶碰觸頁面以後,須要等待一段時間來判斷是否是雙擊(double tap)動做,而不是當即響應單擊(click),等待的這段時間大約是300ms。那麼怎麼消除這個300ms延遲呢?ios

 1.使用fastclick插件,會消除全部click事件的延遲,不推薦使用插件來解決這個問題web

 2.不用click事件,用移動設備提供的原生touch事件,或某些移動端手勢庫提供的tap事件。移動端touch事件提供了 touchstart 、 touchmove 、 touchend等,對於簡單的頁面,能夠把 touchstart 或者 touchend 看成tap來用,這樣能夠解決300ms延遲問題,但並不完美,好比手指接觸目標元素,按住不放,慢慢移出響應區域,依然會觸發 touchstart事件對應的事件處理器(本不該該觸發),touchend也有相似的問題,因此,若是想模擬原生App的點擊事件,須要本身封裝一套tap事件,或者使用手勢庫的tap事件,tap事件原理也很是簡單,是由touchstart和touchend組合而成,首先要判斷touchend和touchstart的偏移距離,而後阻止掉touchend事件300ms以後觸發的click事件,而且始終以touchend事件做爲觸發的必要條件,下面是個demo:api

function tap(node,callback,scope) {
        node.addEventListener(TOUCHSTART, function(e) {
            x = e.touches[0].pageX;
            y = e.touches[0].pageY;
        });
        node.addEventListener(TOUCHEND, function(e) {
            e.stopPropagation();
            e.preventDefault();
            var curx = e.changedTouches[0].pageX;
            var cury = e.changedTouches[0].pageY;
            if (Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) {
                callback.apply(scope, arguments);
            }
        });
}

下面是zepto的tap事件實現源碼:瀏覽器

if (deltaX < 30 && deltaY < 30) {
  tapTimeout = setTimeout(function() {
    var event = $.Event('tap')
    event.cancelTouch = cancelAll
    touch.el.trigger(event)

    if (touch.isDoubleTap) {
      if (touch.el) touch.el.trigger('doubleTap')
      touch = {}
    }else {
      touchTimeout = setTimeout(function() {
        touchTimeout = null
        if (touch.el) touch.el.trigger('singleTap')
        touch = {}
      }, 250)
    }
  }, 0);
}

3、點擊穿透app

   若是某個返回按鈕的位置,剛好在要返回的這個頁面的帶有href屬性的a標籤的範圍內,在點擊返回按鈕後,頁面快速切換到有a標籤的頁面,300ms後觸發了click事件,從而觸發了a標籤的意外跳轉,這個就是典型的點擊穿透問題。罪魁禍首其實就是a標籤跳轉默認是click事件觸發,而移動端的touch事件觸發以後,依然會在300ms後觸發click事件。解決辦法其實在上面一條已經提到了。佈局

 1.就是消費掉touch事件完成後的click事件。

 2.不要混用touch和click事件。顯然不可能都綁定click事件,由於要解決300ms延遲問題(除了fastclick),那麼只能都綁定touch事件,這樣click事件永遠不會被觸發。

 綜上二條,最好的辦法就是本身封裝一個tap事件,而且本身阻止掉300ms後的click事件,完美解決。

 注意:zepto並無阻止click事件,因此使用zepto的tap事件依然會致使點擊穿透問題,你須要手動添加 e.preventDefault() 來阻止click事件。

4、移動端總體佈局

   移動端的總體佈局通常來講能夠分爲上中下三個部分,分別爲 header、main、footer,其中header、footer 是固定高度,分別固定在頁面頂部和頁面底部,而 main 是頁面展現主體內容的部分,而且能夠滾動。要實現這種佈局,有兩種辦法:

 1.最容易想到的就是header和footer爲fixed,body最小高度爲一屏,超出則滾動。這種佈局有個優勢,在ios的safari上頁面的地址欄會隨着 body 的滾動隱藏起來,缺點就是fixed在有input的頁面會有各類兼容性問題(經測試,在固定到主屏幕而且去掉導航欄的狀況下fixed有bug,移動端的各類瀏覽器中是沒有問題的)

 2.採起內滑的策略。具體的實現方式可能略有不一樣,但思路都是在元素內部滾動,而不是body。好比能夠設置header和footer爲absolute,main也爲absolute,而且overflow-y爲auto,或者用彈性佈局的方式。在移動端元素內滑動會有不流暢的問題,建議加上-webkit-overflow-scrolling: touch,這樣就能愉快的滾動了。這種佈局的優勢就是避免了使用fixed,缺點就是移動端瀏覽器中input框的光標閃爍問題(在滾動頁面的時候,光標會錯位,不跟隨input框閃爍,緣由是加了-webkit-overflow-scrollingtouch,致使滑動速度太快來不及重繪,解決方法是在你滑動頁面的時候直接讓input失去焦點,隱藏光標

5、input 的 compositionstart 和 compositionend 事件

   在input中輸入中文的時候,在沒有選定文字前,輸入的每個拼音字母也會觸發input事件,這顯然不是咱們想要的。咱們須要 compositionstart 和 compositionend 事件來處理這個問題。compositionstart會在用戶開始進行非直接輸入的時候觸發,compositionend會在點選候選詞或者點擊「選定」按鈕以後觸發。咱們能夠在compositionstart的時候將input事件上鎖,讓其不執行,在compositionend的時候再解鎖,注意:compositionend 事件是在 input 事件後觸發的。

6、移動端 1px border 實現

 因爲設備高分辨率屏的緣由,邏輯像素的 1px 的 border 在移動設備上會用兩個或三個物理像素來表示,因此看起來會感受很粗。解決方案有不少,但兼容性最好的方案是用僞元素的 box-shadow 或 border 實現 border,而後用 transform: scale(.5) 縮小到原來的一半。具體以下:

.block {
      width: 100px;
      height: 100px;
      margin: 10px;
      position: relative;
      /*border: 1px solid red;*/
}
.block:before {
      content: '';
      position: absolute;
      transform-origin: 0 0;
      top: 0;
      left: 0;
      width: 200%;
      height: 200%;
      border: 1px solid red;
      transform: scale(.5);
}

7、一些小坑

 1.format-detection

<meta name="format-detection" content="telephone=no">

 默認狀況下,設備會自動識別任何多是電話號碼的字符串。設置telephone=no能夠禁用這項功能。

 2.禁止複製、選中文本

 user-select: none;

 3.長時間按住頁面出現閃退或禁止 iOS 彈出各類操做窗口

 -webkit-touch-callout: none;

 4.ios或安卓設備input等元素的特殊樣式

 -webkit-appearance: none;

 5.ios或android下觸摸元素時出現半透明灰色遮罩

 -webkit-tap-highlight-color:rgba(255,255,255,0)

 6.移動端僞類 :active 不起做用

   document.addEventListener('touchstart',function(){},false);

 7.啓用硬件加速使動畫更流暢

 transform: translate3d(0, 0, 0);

 8.旋轉屏幕時,字體大小調整的問題

 -webkit-text-size-adjust:100%;

 9.transition閃屏

 設置子元素以3D的方式呈現

 -webkit-transform-style: preserve-3d;

 設置進行轉換的元素的背面在面對用戶時是否可見

 -webkit-backface-visibility:hidden;

 10.CSS3 rotateY transition 在safari上有bug

 當前轉動的元素,在其上有元素覆蓋它時,或在其下有元素被它覆蓋時,會出現以下bug:

 

 建議設置transform: translateZ(-1000px);

 11.移動端選擇相片

 <input type=file accept="image/*">

 必定要顯示的聲明accept接收的類型

 

 

參考文獻:http://www.cnblogs.com/strick/p/5161660.html

     https://zhuanlan.zhihu.com/p/26141351

     https://zhuanlan.zhihu.com/p/24837233

     http://www.cnblogs.com/wangpenghui522/p/5398137.html

     http://www.cnblogs.com/liulinjie/p/5776337.html

     http://www.haorooms.com/post/phone_web

     http://stackoverflow.com/questions/20737503/mobile-safari-input-caret-does-not-scroll-along-with-overflow-scrolling-touch

相關文章
相關標籤/搜索