天天看點

touchmove在android下面隻觸發一次的奇葩設定

touchmove事件隻觸發一次的問題
  在Android下直接使用touchmove事件會在很多浏覽器中出現每次操作隻觸發一次touchmove的情況。這是因為Android中對觸屏事件奇葩解析造成的,在其它系統上沒有這個情況。我們可以在touchstart事件中加入preventDefalut來解決,但這會帶來其它問題。
運作<meta name="viewport" content="width=device-width,user-scalable=no" />
<input id="coords"></input>
<script>
document.addEventListener("touchmove",function(e){
  var p=e.touches[];
  coords.value="("+p.clientX+","+p.clientY+")";
});
</script>
  這個代碼在Android()下隻有Firefox()可以正常工作,Chrome()、QQ()、UC(),全都都隻能觸發一次touchmove。解決的方法是在touchstart時加上preventDefalut。
document.addEventListener("touchstart",function(e){
  e.preventDefault();
});
  加上這個代碼後所有的浏覽器都可以正常處理touchmove了,但是會出現其它問題。例如這個例子中有個INPUT:TEXT,如果把touchstart事件的預設動作給阻止了我們就無法選中這個控件,無法編輯這個文本控件裡面的文字(有少數浏覽器可以)。這隻是一個例子而已,阻止了touchstart的預設動作會導緻其它,CLICK事件不觸發、超連結失效,等之類的問題。是以,我們除了阻止touchstart的預設動作之外還要對内部的一些特殊元素做處理。讓那些特殊的元素上的事件不冒泡出去,以防止預設動作被阻止。
document.addEventListener("touchstart",function(e){
  /^(?:INPUT|TEXTAREA|A)$/.test(e.target.tagName)||e.preventDefault();
});
  隻有觸發對象不是這些特殊元素時才阻止預設事件,這樣就能避免特殊元素無法實作預設行為。這裡的INPUT、TEXTAREA、A,三個隻是比較常用的需要預設行為的元素,如果有需要還得添加其它的。雖然可以解決問題,但是這麼做也會導緻其它問題。當觸控從這些特殊元素上開始拖動時将和最初的結果一樣touchmove無法正常工作。不過根據使用者的操作習慣通常也不會在這些特殊元素上做拖拽,是以并不會造成太大影響。我目前就這麼解決了,如果大家還有是更好的方法歡迎分享~
           

筆者語:

某日,筆者寫了一個手動觸摸滑動圖檔的控件在pc和ios上運作良好,不過在anroid上面有頓卡現象,痛下心來每次觸碰都列印事件發現每次touchmove都隻觸發一次,也是醉了。