1、安卓設備的select options的坑,儘可能使用各瀏覽器內核都支持的apicss
在添加 OPTION 元素時html
在刪除 OPTION 元素時node
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-scrolling: touch,致使滑動速度太快來不及重繪,解決方法是在你滑動頁面的時候直接讓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