在近期的一個移動端項目中,有一個頁面須要有彈框提示,而且這個彈框經過關閉按鈕關閉。頁面當中使用了 iScroll 來實現頁面局部滾動,在 iScroll 的配置當中把 tap
和 click
事件都開啓了。
代碼以下:html
this.myScroll = new IScroll(this.$refs.wrapper, { mouseWheel: true, click: true, tap: true})
在實現過程當中,遇到了一個奇怪的問題,因爲按鈕的位置與彈框右上角的關閉按鈕位置一致,當我點擊按鈕時,彈框一閃而過。vue
效果以下:git
假如頁面上有兩個元素A和B。B元素在A元素之上。咱們在B元素的touchstart事件上註冊了一個回調函數,該回調函數的做用是隱藏B元素。咱們發現,當咱們點擊B元素,B元素被隱藏了,隨後,A元素觸發了click事件。github
經過上網查找有關資料,翻閱了移動端的書籍,發如今手機端中,事件的觸發順序爲:touchstart
-> touchmove
-> touchend
,而 click
事件有 300ms 的延遲,當 touchstart
事件把B元素隱藏以後,隔了300ms,瀏覽器觸發了 click
事件,可是此時B元素不見了,因此該事件被派發到了A元素身上。若是A元素是一個連接,那此時頁面就會意外地跳轉。segmentfault
touch
事件因爲項目使用的是 Vue.js
,這裏就提供一下 Vue.js
的解決方法。使用了 vue-tap 的一個插件,具體使用方法參看官方文檔,在須要點擊事件的時候,經過 v-tap
指令來綁定。瀏覽器
// main.jsimport vueTap from 'v-tap' // 引入插件Vue.use(vueTap) // 全局註冊
v-tap="{methods:showReceiveModel}" // 在元素上綁定事件
這個也是在網上看到的,也能夠解決點透問題,使用方法能夠看 fastclick 的文檔,在這裏提供一下 Vue.js
的引入及使用app
import FastClick from 'fastclick'; // 引入插件FastClick.attach(document.body, options); // 使用 fastclick
最終沒有使用這個方案是由於有一些小 bug ,如 Fastclick 致使click事件觸發兩次的問題。ide
tap
一詞對於 tap
這個詞,用過 Zepto
或 KISSY
等移動端js庫的人確定對tap事件不陌生,作PC頁面時綁定 click
,相應地手機頁面就綁定 tap
。但原生的 touch
事件自己是沒有 tap
的,js庫裏提供的tap事件都是模擬出來的。函數
手機上響應 click
事件會有300ms的延遲,那麼這300ms究竟是幹嗎了?瀏覽器在 touchend
後會等待約300ms,緣由是判斷用戶是否有雙擊(double tap)
行爲。若是沒有 tap
行爲,則觸發 click
事件,而雙擊過程當中就不適合觸發 click
事件了。由此能夠看出 click
事件觸發表明一輪觸摸事件的結束。gradle
既然說tap事件是模擬出來的,咱們能夠看下 Zepto
對 singleTap 事件的處理。見 源碼 136-143 行,能夠看出在 touchend
響應 250ms 無操做後,則觸發 singleTap
。
《移動 Web 手冊》