Maison > Article > interface Web > Comment implémenter une bibliothèque de gestes en JavaScript
Cet article vous présentera comment implémenter la comparaison de dates dans JS. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Nous allons d'abord déclencher un événement de démarrage, c'est-à-dire lorsque notre doigt touche l'écran A. événement déclenché. Il y aura trois situations à ce moment-là :
tap
comportement de clic pan start
glisserpress start
en appuyant sur Notre première étape consiste donc à ajouter un gestionnaire start
à la fonction setTimout
.
let handler;let start = point => { handler = setTimeout(() => { console.log('presss '); }, 500);};
De manière générale, press
est un comportement courant parmi nous. Mais en réalité, il s’agit d’un événement de démarrage de presse, suivi d’un événement de fin de presse. Nous pouvons également appeler cela collectivement l'événement press
, et les utilisateurs de cette bibliothèque de gestes n'ont alors qu'à écouter cet événement press
. Dans de rares cas, il est nécessaire d'écouter l'événement press end
.
Ce que nous devons noter ici, c'est que lorsque nous déclenchons d'autres événements, ce setTimout de 500 millisecondes peut être annulé. Nous devons donc donner un handler
à cette logique et la mettre dans la portée globale afin que d'autres événements puissent obtenir cette variable et l'utiliser pour annuler cette logique de traitement.
Ensuite, nous écouterons l'événement pan
qui se déplace de 10 pixels. Ici, nous devons enregistrer le x lorsque l'utilisateur touche l'écran. au début et la coordonnée y Lorsque l'utilisateur déplace le doigt, la distance entre la position nouvellement déplacée et la position initiale est calculée en continu. Si cette distance dépasse 10px, notre événement pan start
peut être déclenché.
Nous devons donc d'abord ajouter les enregistrements de coordonnées de startX
et startY
dans la fonction de démarrage. Ce qu'il convient de noter ici, c'est que parce que ces deux valeurs seront utilisées à plusieurs endroits, donc Doit être déclaré dans la portée globale.
Calculez ensuite la distance de diamètre entre le point de contact actuel et le point de départ dans la fonction de déplacement. Ici, nous devons utiliser la formule de calcul du diamètre en mathématiques z 2 x^2 + y^2 = z^2x 2 +o 2 =z 2 , et x voici la distance sur l'axe x entre la coordonnée x du point de contact actuel - la coordonnée x du point de départ, et y est la distance sur l'axe y calculée à partir de la coordonnée y du point de départ actuel - la coordonnée y du point de départ. La somme finale des deux distances élevées à la puissance deux est la distance diamètre élevée à la puissance deux.
Dans le code, on essaie généralement d'éviter d'utiliser l'opération radicale, car l'opération radicale aura un certain impact sur les performances. Nous savons que ce que nous devons en fin de compte juger, c'est si la distance de diamètre est supérieure à 10 pixels fixes. C'est-à-dire que z = 10 et que la deuxième puissance de z est 100, nous pouvons donc déterminer directement si la distance entre les diamètres est supérieure à 100.
Une autre chose à noter ici est que lorsque notre doigt bouge de plus de 10px, si notre doigt ne quitte pas l'écran mais recule, alors nous ne sommes plus à 10px du point de départ. Mais il s'agit en fait d'un événement panoramique, car nous avons parcouru une distance de plus de 10 px, et tous les mouvements après cette distance sont des événements panoramiques.
Nous avons donc besoin d'un état isPan
Lorsque le premier mouvement dépasse 10px, l'événement pan-start
sera déclenché, et isPan
est défini sur true, et tous les mouvements suivants déclencheront des événements pan
. .
Selon l'événement press
dont nous avons parlé ci-dessus, s'il y a un mouvement dans les 0,5 secondes après avoir appuyé sur notre doigt, alors l'événement press
sera annulé. Nous devons donc ici clearTimeout
effacer le pressstart
de handler
.
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'); }};
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高级教程】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!