Noh | エンジニア向け情報共有コミュニティ
Signup / Login

JSでドラッグの時にクリック判定しない方法

y
yosi2024/08/04 6:07

JSでドラッグの時にクリック判定しない方法を教えて

A
Answerer AIPowered by gpt-3.5-turbo

ドラッグ操作中にクリック判定を行わない方法は、イベントオブジェクトのcancelBubbleプロパティを使用することです。

以下のように、mousedownイベントのハンドラー内でcancelBubbleプロパティを設定することで、マウスのドラッグ中にクリックイベントがキャンセルされます。

element.addEventListener('mousedown', function(event) { // クリックイベントをキャンセル event.cancelBubble = true; });

このようにすることで、マウスのドラッグ中に他のボタンのクリックイベントが発生しなくなります。

y
yosi2024/08/04 6:09

mouseupやonclick含めた実際のコード例を書いてください。

A
Answerer AIPowered by gpt-3.5-turbo

以下に実際のコード例を示します。

<div id="drag-element" style="width: 200px; height: 200px; background-color: #ccc; cursor: move;"></div> <script> // ドラッグ中にクリックイベントをキャンセルするためのフラグ let isDragging = false; const dragElement = document.getElementById('drag-element'); // ドラッグ開始時のイベントリスナー dragElement.addEventListener('mousedown', function(event) { isDragging = true; // クリックイベントをキャンセル event.cancelBubble = true; }); // ドラッグ終了時のイベントリスナー dragElement.addEventListener('mouseup', function(event) { isDragging = false; }); // ドラッグ要素のクリックイベントリスナー dragElement.addEventListener('click', function(event) { // ドラッグ中はクリックイベントを無効化 if (isDragging) { event.preventDefault(); event.stopPropagation(); } else { // ドラッグ中でない場合のクリック時の処理 console.log("クリックイベントが発生しました"); } }); </script>

このコードでは、指定したIDの要素 (drag-element) をドラッグ可能な要素として設定しています。マウスボタンが押されると、mousedownイベントが発生し、フラグ isDraggingtrue に設定されます。このとき、mousedownイベントの中でcancelBubbleプロパティを設定しています。

マウスボタンが離されると、mouseupイベントが発生し、フラグ isDraggingfalse に設定されます。

また、ドラッグ要素自体にクリックイベントのリスナーを追加しています。isDraggingtrue の場合、ドラッグ中のためクリックイベントをキャンセルします。isDraggingfalse の場合は、通常のクリック時の処理が行われます。

このようにすることで、ドラッグ中にクリックイベントが発生しないようになります。

y
yosi2024/08/04 6:33

mouseupの方がclickより先に実行されるので、機能しないと思います。

A
Answerer AIPowered by gpt-3.5-turbo

ご指摘いただき、申し訳ありません。確かに、mouseupイベントがclickイベントよりも早く発生する場合があります。

修正されたコードを以下に示します。

<div id="drag-element" style="width: 200px; height: 200px; background-color: #ccc; cursor: move;"></div> <script> // ドラッグ中にクリックイベントをキャンセルするためのフラグ let isDragging = false; const dragElement = document.getElementById('drag-element'); // ドラッグ開始時のイベントリスナー dragElement.addEventListener('mousedown', function(event) { isDragging = true; // クリックイベントをキャンセル event.cancelBubble = true; }); // クリックイベントの前に発生する mouseup イベント // ドラッグ中はクリックイベントをキャンセルする dragElement.addEventListener('mouseup', function(event) { // ドラッグ中の場合は、クリックイベントをキャンセル if (isDragging) { event.preventDefault(); event.stopPropagation(); } }); // ドラッグ要素のクリックイベントリスナー dragElement.addEventListener('click', function(event) { // ドラッグ中はクリックイベントを無効化 if (isDragging) { event.preventDefault(); event.stopPropagation(); } else { // ドラッグ中でない場合のクリック時の処理 console.log("クリックイベントが発生しました"); } }); </script>

この修正により、mouseupイベントがclickイベントよりも先に発生しても、ドラッグ中にクリックイベントがキャンセルされるようになります。お手数をおかけしてしまい、申し訳ございませんでした。ご確認いただければ幸いです。

y
yosi2024/08/04 7:04

ドラッグしてないときもisDragging == trueとなるのが微妙なので最終的に以下のような感じにした。
mousedownのときに取得した座標とclickのときに取得した座標が一致しているときだけ、処理を行うようにしている

let mousedownPosition: { x: number, y: number } | undefined window.addEventListener("mousedown", (event) => { mousedownPosition = { x: event.clientX, y: event.clientY } }) const onClick = (event: MouseEvent) => { if ( event.clientX != mousedownPosition?.x || event.clientY != mousedownPosition?.y ) { return } console.log("onClick ") } window.addEventListener("click", onClick)
コメントするにはログインが必要です
y
yosi