In diesem Artikel erfahren Sie, wie Sie den Datumsgrößenvergleich in JS implementieren. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.
Zuerst lösen wir ein Startereignis aus, das erste Ereignis, das ausgelöst wird, wenn unser Finger den Bildschirm berührt. Zu diesem Zeitpunkt wird es drei Situationen geben:
Tap
-Klickverhalten darstellttap
点击的行为pan start
拖动的行为press start
按压的行为所以我们第一步就是在 start
函数中加入一个 setTimout
的 handler 处理程序。
let handler;let start = point => { handler = setTimeout(() => { console.log('presss '); }, 500);};
一般来说 press
是我们比较常见的一个行为。但是实际上这里是 press start 事件,后面还会跟随着一个 press end 的事件。我们也可以统称这个为 press
事件,然后这个手势库的使用者只需要监听这个 press
事件即可,极少的情况下是需要监听 press end
事件的。
这里我们需要注意的是,当我们触发其他的事件的时候,这个 500 毫秒的 setTimout 是有可能会被取消掉的。所以我们需要给这段逻辑一个 handler
,并且放在全局作用域中,让其他事件可以获取到这个变量,并且可使用它取消掉这个处理逻辑。
接下来我们就去监听移动 10px 的 pan
事件,这里就需要我们记录一开始用户触摸屏幕时的 x 和 y 坐标,当用户移动手指的时候,持续计算新移动到的位置与初始位置的距离。如果这个距离超过了 10px 就可以触发我们的 pan start
的事件了。
所以首先我们需要在 start 函数中加入 startX
和 startY
的坐标记录,这里要注意的是,因为这两个值都是会在多个地方被使用的,所以也是需要在全局作用域中声明。
然后在 move 函数中计算当前触点与起点的直径距离。这里我们需要用到数学中的直径运算公式 z 2 x^2 + y^2 = z^2x 2 +y 2 =z 2 ,而这里面的 x 是 当前触点的 x 坐标 - 起点的 x 坐标 的 x 轴的距离, y 就是 当前出点的 y 坐标 - 起点的 y 坐标 运算出来的 y 轴的距离。最终两个距离二次幂相加就是直径距离的二次幂。
在代码中我们一般都会尽量避免使用根号运算,因为根号运算会对性能有一定的影响。我们知道最终要判断的是直径距离是否是大于一个固定的 10px。那就是说 z = 10,而 z 的二次幂就是 100,所以我们直接判断这个直径距离是否大于 100 即可。
这里还有一个需要注意的,就是当我们手指移动超过 10px 之后,如果我们手指没有离开屏幕而是往回移动了,这样的话我们距离起点已经不够 10px了。但是这个其实也是算 pan 事件,因为我们确实有移动超过 10px 距离,超过这个距离之后所有的移动都是属于 pan 事件。
所以我们需要一个 isPan
的状态,第一次移动超出 10px 的时候,就会触发 pan-start
事件,并且把 isPan
置为 true,而后面的所有移动都会触发 pan
事件。
根据我们上面讲到的 press
事件,如果我们按下手指后 0.5 秒内出现了移动,那么 press
事件就会被取消。所以这里我们就需要 clearTimeout
把 pressstart
的 handler
Dies kann durch Abhören des Endereignisses erreicht werden
Dies ist das Verhalten des Pan-Start
-Ziehens
Start drücken
🎜Wir können ein setTimeout hinzufügen, um 🎜Press-Ereignis🎜🎜 zu implementieren 🎜🎜Also ist unser erster Schritt, start < /code> Fügen Sie der Funktion einen <code>setTimout
-Handler hinzu. 🎜let handler;let startX, startY;let isPan = false;let start = point => { (startX = point.clientX), (startY = point.clientY); isPan = false; handler = setTimeout(() => { console.log('pressstart'); }, 500);};let move = point => { let dx = point.clientX - startX, dy = point.clientY - startY; let d = dx ** 2 + dy ** 2; if (!isPan && d > 100) { isPan = true; console.log('pan-start'); clearTimeout(handler); } if (isPan) { console.log(dx, dy); console.log('pan'); }};
drücken
ein häufiges Verhalten bei uns. Aber eigentlich handelt es sich hierbei um ein Press-Start-Event, gefolgt von einem Press-Ende-Event. Wir können dies auch gemeinsam als press
-Ereignis bezeichnen, und dann müssen Benutzer dieser Gestenbibliothek nur auf dieses press
-Ereignis hören Ende drücken
Ereignis. 🎜🎜Was wir hier beachten müssen, ist, dass dieses 500-Millisekunden-setTimout möglicherweise abgebrochen wird, wenn wir andere Ereignisse auslösen. Daher müssen wir dieser Logik einen handler
geben und ihn in den globalen Bereich einfügen, damit andere Ereignisse diese Variable abrufen und zum Abbrechen dieser Verarbeitungslogik verwenden können. „Pan-Event“: Das pan
-Ereignis, das sich um 10 Pixel bewegt. Hier müssen wir die x- und y-Koordinaten aufzeichnen, wenn der Benutzer zu Beginn seinen Finger bewegt Position und die Ausgangsposition. Wenn dieser Abstand 10 Pixel überschreitet, kann unser pan start
-Ereignis ausgelöst werden. 🎜🎜Also müssen wir zuerst die Koordinatendatensätze von startX
und startY
in der Startfunktion hinzufügen. Hierbei ist zu beachten, dass diese beiden Werte vorhanden sind an mehreren Stellen verwendet wird, muss es daher auch im globalen Bereich deklariert werden. 🎜🎜Anschließend berechnen Sie den Durchmesserabstand zwischen dem aktuellen Kontaktpunkt und dem Startpunkt in der Bewegungsfunktion. Hier müssen wir die Durchmesserberechnungsformel in der Mathematik z 2 x^2 + y^2 = z^2x verwenden
2
+y
2
=z
2
, und x ist hier der x-Achsenabstand zwischen der x-Koordinate des aktuellen Kontaktpunkts – der die y-Koordinate des Startpunkts. Die endgültige Summe der beiden Abstände hoch zwei ist der Durchmesserabstand hoch hoch zwei. 🎜🎜 Im Code versuchen wir im Allgemeinen, die Verwendung radikaler Operationen zu vermeiden, da radikale Operationen einen gewissen Einfluss auf die Leistung haben. Wir wissen, dass wir letztendlich beurteilen müssen, ob der Durchmesserabstand größer als feste 10 Pixel ist. Das heißt, z = 10 und die zweite Potenz von z ist 100, sodass wir direkt bestimmen können, ob der Durchmesserabstand größer als 100 ist. 🎜🎜Eine weitere Sache, die hier zu beachten ist, ist, dass wir nicht mehr 10 Pixel vom Startpunkt entfernt sind, wenn sich unser Finger um mehr als 10 Pixel bewegt, wenn unser Finger den Bildschirm nicht verlässt, sondern sich zurückbewegt. Dabei handelt es sich jedoch tatsächlich um ein Pan-Ereignis, da wir uns über eine Distanz von mehr als 10 Pixel bewegt haben und alle Bewegungen nach dieser Distanz Pan-Ereignisse sind. 🎜🎜Wir benötigen also einen isPan
-Status. Wenn die erste Bewegung 10 Pixel überschreitet, wird das pan-start
-Ereignis ausgelöst und isPan
> auf gesetzt wahr, und alle nachfolgenden Bewegungen lösen das pan
-Ereignis aus. 🎜🎜Gemäß dem oben erwähnten press
-Ereignis wird das press
-Ereignis abgebrochen, wenn innerhalb von 0,5 Sekunden nach dem Drücken unseres Fingers eine Bewegung erfolgt. Hier benötigen wir also clearTimeout
, um den handler
von pressstart
zu löschen. 🎜let handler;let startX, startY;let isPan = false, isPress = false, isTap = false;let start = point => { (startX = point.clientX), (startY = point.clientY); isPan = false; isTap = true; isPress = false; handler = setTimeout(() => { isPan = false; isTap = false; isPress = true; console.log('press-start'); handler = null; }, 500);};let move = point => { let dx = point.clientX - startX, dy = point.clientY - startY; let d = dx ** 2 + dy ** 2; if (!isPan && d > 100) { isPan = true; isTap = false; isPress = false; console.log('pan-start'); clearTimeout(handler); } if (isPan) { console.log(dx, dy); console.log('pan'); }};let end = point => { if (isTap) { console.log('tap'); clearTimeout(handler); }};
Tap 的这个逻辑我们可以在 end 事件里面去检查。首先我们默认有一个 isTap
等于 true 的状态,如果我们触发了 pan 事件的话,那就不会去触发 tap 的逻辑了,所以 tap 和 pan 是互斥的关系。但是为了不让它们变得很耦合,所以我们不使用原有的 isPan 作为判断状态,而是另外声明一个 isTap
的状态来记录。
这里我们 tap 和 pan 都有单独的状态,那么我们 press 也不例外,所以也给 press 加上一个 isPress
的状态,它的默认值是 false。如果我们 0.5 秒的定时器被触发了,isPress
也就会变成 true。
既然我们给每个事件都加入了状态,那么这里我们就给每一个事件触发的时候设置好这些状态的值。
如果我们发现用户没有移动,也没有按住触屏超过 0.5 秒,当用户离开屏幕时就会调用 end 函数,这个时候我们就可以认定用户的操作就是 tap。这里我们要注意的是,我们 press 的 0.5 秒定时器是没有被关闭的,所以我们在 isTap 的逻辑中需要 clearTimeout(handler)
。
说到取消 press 定时器,其实我们 handler 的回调函数中,也需要做一个保护代码逻辑,在触发了 press-start 之后,我们需要保证每次点击屏幕只会触发一次,所以在 setTimout 的回调函数中的最后,我们需要加上 handler = null
。这样只要 press-start 触发了,就不会再被触发。
let handler;let startX, startY;let isPan = false, isPress = false, isTap = false;let start = point => { (startX = point.clientX), (startY = point.clientY); isPan = false; isTap = true; isPress = false; handler = setTimeout(() => { isPan = false; isTap = false; isPress = true; console.log('press-start'); handler = null; }, 500);};let move = point => { let dx = point.clientX - startX, dy = point.clientY - startY; let d = dx ** 2 + dy ** 2; if (!isPan && d > 100) { isPan = true; isTap = false; isPress = false; console.log('pan-start'); clearTimeout(handler); } if (isPan) { console.log(dx, dy); console.log('pan'); }};let end = point => { if (isTap) { console.log('tap'); clearTimeout(handler); }};
到了最后这里我们要处理的就是所有的结束时间,包括 press-end
和 pan-end
。
这两个 end 事件都会在 end 函数中判断所得,如果在用户操作的过程中触发了 pan-start
或者 press-start
事件,到了 end 函数这里,对应的状态就会是 true。
所以我们对 end 函数做了以下改造:
let end = point => { if (isTap) { console.log('tap'); clearTimeout(handler); } if (isPan) { console.log('pan-end'); } if (isPress) { console.log('press-end'); }};
最后我们需要在 cancel 事件触发的时候,清楚掉 press 事件的 setTimeout。既然我们的操作被打断了,那也不可能会触发我们的长按事件了。
// 加入 cancellet cancel = point => { clearTimeout(handler); console.log('cancel');};
我们除了 flick
的逻辑,我们已经完成所有手势库里面的事件了。并且也能正确的区分这几种手势操作了。
【推荐学习:javascript高级教程】
Das obige ist der detaillierte Inhalt vonSo implementieren Sie eine Gestenbibliothek in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!