Heim >Web-Frontend >js-Tutorial >Verwenden Sie natives JS, um Tap-Ereignisse zu kapseln und die 300-ms-Verzögerung auf dem mobilen Endgerät zu beheben
FastClick
Es gibt mittlerweile ein fertiges Plug-in Fastclick, das dieses Problem lösen kann, aber auch Nachteile hat:
Die Größe der neuesten Version des Plug-ins auf GitHub ist 25,4 KB groß, Leichtgewicht ist der Trend und Energieeinsparung ist der Trend in der Provinz.
Die Kernidee besteht darin, die Standardklickzeit abzubrechen, den Typ des aktuellen Dom-Knotens zu bestimmen und entsprechende Vorgänge durchzuführen. Dieser Beurteilungsprozess ist relativ umständlich.
MyTapEvent
Ich arbeite derzeit an einem WeChat-Projekt. Aufgrund bestimmter Nachteile des Fastclick-Plugins habe ich ein einfaches Tap-Event entwickelt:
Denken
Ein Tap-Ereignis umfasst drei Zustände: Touchstart, Touchmove (leichte Bewegung) und Touchend
Die Callback-Methode wird nach Touchend ausgeführt
Abbrechen des Klicks entsprechend Die Standardbeurteilung des Chrome-Browsers. Wenn der Bewegungsumfang und der Fingerversatz (horizontal oder vertikal) 15 Pixel überschreiten, wird dies als Scrollen erkannt und das Tippereignis wird abgebrochen.
Wenn der Finger gedrückt wird zu lang, wird es nicht als Klick betrachtet.
Verwenden Sie HTMLElement, um den Prototyp zu erweitern, um ein Ereignis einfach hinzuzufügen
Verwenden Sie den Singleton-Modus, um sicherzustellen, dass er nur einmal geladen wird
Okay, sobald Sie sich eingelebt haben, wird der Code viel klarer zu schreiben sein:
if (!HTMLElement.prototype.addTapEvent) { HTMLElement.prototype.addTapEvent = function(callback) { var tapStartTime = 0, tapEndTime = 0, tapTime = 500, //tap等待时间,在此事件下松开可触发方法 tapStartClientX = 0, tapStartClientY = 0, tapEndClientX = 0, tapEndClientY = 0, tapScollHeight = 15, //水平或垂直方向移动超过15px测判定为取消(根据chrome浏览器默认的判断取消点击的移动量) cancleClick = false; this.addEventListener('touchstart', function() { tapStartTime = event.timeStamp; var touch = event.changedTouches[0]; tapStartClientX = touch.clientX; tapStartClientY = touch.clientY; cancleClick = false; }) this.addEventListener('touchmove', function() { var touch = event.changedTouches[0]; tapEndClientX = touch.clientX; tapEndClientY = touch.clientY; if ((Math.abs(tapEndClientX - tapStartClientX) > tapScollHeight) || (Math.abs(tapEndClientY - tapStartClientY) > tapScollHeight)) { cancleClick = true; } }) this.addEventListener('touchend', function() { tapEndTime = event.timeStamp; if (!cancleClick && (tapEndTime - tapStartTime) <= tapTime) { callback(); } }) } }
Verwendung
HTMLElement.addTapEvent(function(){ //do something...}) 如:document.querySelect('#test').addTapEvent(function(){ alert('this is a tap event'); })
Fall
Hier ist Ein mobiler Fall, der auch das Wissen über Schließungen beinhaltet, und die letzten 30 Elemente sind Klickereignisse. Sie können den Effekt auf Ihrem Mobiltelefon ausprobieren und den Unterschied zwischen den beiden Methoden spüren:
<style media="screen"> li { padding: 20px; }</style><!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-touch-fullscreen" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="format-detection" content="telephone=no,email=no"> <meta name="x5-orientation" content="portrait"> <title>test</title> </head> <body> <ul></ul> </body> <script type="text/javascript"> if (!HTMLElement.prototype.addTapEvent) { HTMLElement.prototype.addTapEvent = function(callback) { var tapStartTime = 0, tapEndTime = 0, tapTime = 500, //tap等待时间,在此事件下松开可触发方法 tapStartClientX = 0, tapStartClientY = 0, tapEndClientX = 0, tapEndClientY = 0, tapScollHeight = 15, //水平或垂直方向移动超过15px测判定为取消(根据chrome浏览器默认的判断取消点击的移动量) cancleClick = false; this.addEventListener('touchstart', function() { tapStartTime = event.timeStamp; var touch = event.changedTouches[0]; tapStartClientX = touch.clientX; tapStartClientY = touch.clientY; cancleClick = false; }) this.addEventListener('touchmove', function() { var touch = event.changedTouches[0]; tapEndClientX = touch.clientX; tapEndClientY = touch.clientY; if ((Math.abs(tapEndClientX - tapStartClientX) > tapScollHeight) || (Math.abs(tapEndClientY - tapStartClientY) > tapScollHeight)) { cancleClick = true; } }) this.addEventListener('touchend', function() { tapEndTime = event.timeStamp; if (!cancleClick && (tapEndTime - tapStartTime) <= tapTime) { callback(); } }) } } var ul = document.querySelector('ul'); for (var i = 1; i <= 20; i++) { var li = document.createElement('li'); li.innerHTML = i; li.addTapEvent(function() { var x = i; return function() { alert(x); } }()) ul.appendChild(li); } for (var j = 21; j <= 50; j++) { var li = document.createElement('li'); li.innerHTML = j; li.onclick = function() { var x = j; return function() { alert(x); } }() ul.appendChild(li); } </script></html>