在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后真正触发的click事件阻止掉
const FastClick = (function(){ function attach(root) { let targetElement = null root.addEventListener('touchstart', function () { targetElement = event.target }) root.addEventListener('touchend', function (event) { event.preventDefault() let touch = event.changedTouches[0] let 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) }) } return { attach } })() FastClick.attach(document.body)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>fastclick简单实现-饥人谷</title> <meta name="viewport" content="width=device-width"> </head> <body> <p>用手指放大页面,再点链接测试</p> <p id="log"></p> <div class="box box1"> <h3>未使用fastclick有岩石</h3> <a id="link1" href="#1">链接1</a> <a id="link2" href="#2">链接2</a> </div> <div class="box box2"> <h3>使用fastclick无延时</h3> <a id="link3" href="#3">链接3</a> <a id="link4" href="#4">链接4</a> </div> <script> const $ = selector => document.querySelector(selector) const $$ = selector => document.querySelectorAll(selector) const log = str => $('#log').innerText = str const FastClick = (function(){ function attach(root) { let targetElement = null root.addEventListener('touchstart', function () { targetElement = event.target }) root.addEventListener('touchend', function (event) { event.preventDefault() let touch = event.changedTouches[0] let 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) }) } return { attach } })() FastClick.attach($('.box2')) let start $$('a').forEach($link => { $link.ontouchend = () => { start = Date.now() } }) window.onhashchange = () => { log(`click link ${location.hash}: ${Date.now() - start }ms`) } </Script> </body> </html>
测试时,先用双指放大页面,此时才会出现点击延时。 分别对比使用fastclick处理过的区域和未处理过的区域。 复制链接到手机浏览器 http://js.jirengu.com/goxaq