為什么使用FastClick
在移動端H5開發(fā)過程中郑藏,關(guān)于點觸可能會遇到如下兩個問題:
- 手動點擊與真正觸發(fā)
click
事件會存在300ms的延遲 - 點擊穿透問題(點擊行為會穿透元素觸發(fā)非父子關(guān)系元素的事件)
延遲的存在時因為瀏覽器想知道你是否在進行雙擊操作按价;而點擊穿透是因為300ms延遲觸發(fā)時的副作用休吠。而使用fastclick能很好的解決這個問題,增加使用者的體驗。
可以不使用的場景
不必使用的瀏覽器環(huán)境如下:
- Android + Chrome >32
- Android + Chrome +
meta="user-scalable=no"
- 部分黑莓手機環(huán)境(可略過)
- 部分WindowsPhone環(huán)境(可略過)
這部分的判斷在下面的方法中有體現(xiàn),如果當前環(huán)境支持快速點擊杠纵,則FastClick會自動跳過初始化。
FastClick.notNeeded = function(layer) { ... }
原理過程
如果完整的描述FastClick過程需要考慮多種場景的兼容钩骇,這里就描述一個按鈕點擊過程的處理比藻,下面是用來描述的代碼:
// 業(yè)務(wù)代碼
var $test = document.getElementById('test')
$test.addEventListener('click', function () {
console.log('1 click')
})
// FastClick簡單實現(xiàn)
var targetElement = null
document.body.addEventListener('touchstart', function () {
// 記錄點擊的元素
targetElement = event.target
})
document.body.addEventListener('touchend', function (event) {
// 阻止默認事件(屏蔽之后的click事件)
event.preventDefault()
var touch = event.changedTouches[0]
// 合成click事件,并添加可跟蹤屬性forwardedTouchEvent
var clickEvent = document.createEvent('MouseEvents')
clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null)
clickEvent.forwardedTouchEvent = true // 自定義的
targetElement.dispatchEvent(clickEvent)
})
這里進行過程說明:
1. 業(yè)務(wù)正常使用click綁定事件
2. 在document.body綁定touchstart
和touchend
touchstart
用于記錄當前點擊的元素targetElement倘屹;
touchend
- 阻止默認事件(屏蔽之后的click事件)
- 合成click事件银亲,并添加可跟蹤屬性forwardedTouchEvent
- 在targetElement上觸發(fā)
click
事件 - targetElement上綁定的事件立即執(zhí)行,完成FastClick
3. 執(zhí)行業(yè)務(wù)自己的click事件
總結(jié)
以上就完成了模擬FastClick纽匙,是不是很簡單务蝠。事件的執(zhí)行過程需要了解:touch事件先于mouse事件先于click執(zhí)行,因此可以在document.body上綁定事件用于監(jiān)聽點觸行為烛缔,根據(jù)需要模擬click觸發(fā)真正需要響應(yīng)的元素馏段。
(完)