ホームページ > 記事 > ウェブフロントエンド > JavaScript でジェスチャ ライブラリを実装する方法
この記事では、JS で日付比較を実装する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
まず、開始イベントをトリガーします。つまり、指が画面に触れたとき、トリガーされたイベント。この時点では 3 つの状況が考えられます。
タップ
クリック動作を構成します ドラッグの動作です
setTimout ハンドラー ハンドラーを
start 関数に追加することです。
let handler;let start = point => { handler = setTimeout(() => { console.log('presss '); }, 500);};一般的に、
press は私たちにとって一般的な行動です。しかし実際には、これはプレス開始イベントとそれに続くプレス終了イベントです。このイベントをまとめて
press と呼ぶこともでき、その場合、このジェスチャ ライブラリのユーザーは、この
press イベントをリッスンするだけで済みます。まれに、
press をリッスンする必要がある場合もあります。終了 イベント。
handler を与え、グローバル スコープに置く必要があります。
pan イベントをリッスンします。ここでは、最初のユーザー タッチを記録する必要があります。ユーザーが指を動かすと、画面の x 座標と y 座標は、新しく移動した位置と最初の位置の間の距離を計算し続けます。この距離が 10px を超える場合、
pan start イベントがトリガーされる可能性があります。
startX と
startY の座標レコードを start 関数に追加する必要があります。ここで注意すべき点は、これら 2 つの値は、複数の場所で使用されるため、グローバル スコープでも宣言する必要があります。
isPan の状態が必要です。最初の動きが 10px を超えると、
pan-start イベントがトリガーされ、
isPan が設定されますtrue に設定すると、後続のすべての動きが
pan イベントをトリガーします。
press イベントによると、指を押してから 0.5 秒以内に動きがあった場合、
press イベントはキャンセルされます。したがって、ここでは
pressstart の
handler をクリアするために
clearTimeout が必要です。
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高级教程】
以上がJavaScript でジェスチャ ライブラリを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。