標籤:綁定 單擊 options eve input框 標籤 測試 布局 head
一、安卓裝置的select options的坑,盡量使用各瀏覽器核心都支援的api
在添加 OPTION 元素時
- 如果需要向指定索引前插入 OPTION,可以使用 options.add(option, index);
- 如果需要向 SELECT 尾部添加 OPTION,可以使用 options.add(option);
- 如果需要向指定索引處添加(或更改) OPTION,可以使用 options[index] = option。
在刪除 OPTION 元素時
- 如果想刪除指定索引處的 OPTION 元素,可以使用 select.remove(index) 或 options[index] = null;
- 如果想刪除某個指定的 OPTION 元素,可以使用 select.remove(option);
- 如果想刪除 SELECT 中所有 OPTION,可以使用 select.length = 0 或 options.length = 0。
二、移動端click事件300ms延遲
click事件,在移動端,會經過300ms的延遲後才觸發。原因是,行動瀏覽器提供一個特殊的功能:雙擊(double tap)放大,使用者碰觸頁面之後,需要等待一段時間來判斷是不是雙擊(double tap)動作,而不是立即響應單擊(click),等待的這段時間大約是300ms。那麼怎麼消除這個300ms延遲呢?
1.使用fastclick外掛程式,會消除所有click事件的延遲,不推薦使用外掛程式來解決這個問題
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:
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);}
三、點擊穿透
如果某個返回按鈕的位置,恰好在要返回的這個頁面的帶有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事件。
四、移動端整體布局
移動端的整體布局一般來說可以分為上中下三個部分,分別為 header、main、footer,其中header、footer 是固定高度,分別固定在頁面頂部和頁面底部,而 main 是頁面展示主體內容的部分,並且可以滾動。要實現這種布局,有兩種辦法:
1.最容易想到的就是header和footer為fixed,body最小高度為一屏,超出則滾動。這種布局有個優點,在ios的safari上頁面的地址欄會隨著 body 的滾動隱藏起來,缺點就是fixed在有input的頁面會有各種相容性問題(經測試,在釘選到首頁並且去掉導覽列的情況下fixed有bug,在安卓或者ios的webview中也會有bug,移動端的各種瀏覽器中是沒有問題的),並且全域滾動不同的tab之間共用一個捲軸,顯然不是我們想要的。
2.採取內滑的策略。具體的實現方式可能略有不同,但思路都是在元素內部滾動,而不是body。比如可以設定header和footer為absolute,main也為absolute,並且overflow-y為auto,或者用彈性布局的方式。在移動端元素內滑動會有不流暢的問題,建議加上-webkit-overflow-scrolling: touch,這樣就能愉快的滾動了。這種布局的優點就是避免了使用fixed,而且每個局部滾動擁有自己的捲軸,缺點就是移動端瀏覽器中input框的游標閃爍問題(在滾動頁面的時候,游標閃爍會有來不及重繪的情況出現,導致游標錯位,不跟隨input框閃爍)
五、input 的 compositionstart 和 compositionend 事件
在input中輸入中文的時候,在沒有選定文字前,輸入的每一個拼音字母也會觸發input事件,這顯然不是我們想要的。我們需要 compositionstart 和 compositionend 事件來處理這個問題。compositionstart會在使用者開始進行非直接輸入的時候觸發,compositionend會在點選候選詞或者點擊「選定」按鈕之後觸發。我們可以在compositionstart的時候將input事件上鎖,讓其不執行,在compositionend的時候再解鎖,注意:compositionend 事件是在 input 事件後觸發的。
六、移動端 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);}
七、一些小坑
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
總結在移動端碰到的坑