Firefox 112.0.1 では何かしらの HTML 要素をドラッグする時、マウスの位置を取得するのが難しくなります。例えば、次のコードは Microsoft Edge や Google Chrome ではマウスの位置を取得して現在地の情報を表示し続けられます。一方で Firefox でこれを動かすと X も Y も0のまま微動だにしません。この仕様の差異を吸収するコードを紹介します。
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Example</title>
</head>
<body>
<div id="drag-element" draggable="true" style="width: 100px; height: 100px; background-color: red; position: absolute; top: 50px; left: 50px;"></div>
<p>Mouse position: <span id="mouse-position"></span></p>
<script>
var dragElement = document.getElementById("drag-element");
var mousePosition = document.getElementById("mouse-position");
dragElement.addEventListener("drag", function(event) {
var currentMouseX = event.clientX;
var currentMouseY = event.clientY;
mousePosition.innerHTML = "X: " + currentMouseX + ", Y: " + currentMouseY;
});
</script>
</body>
</html>
Firefox でドラッグ中マウスの位置を取得するプロパティはいくつかマウスの位置を取得しない挙動を取ります(ドラッグ元の要素の位置を取得し続けてる?)。その中でも dragover イベントはマウスの位置を取得する挙動を信用できます。これを利用したコードが次です。
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Example</title>
</head>
<body>
<div id="drag-element" draggable="true" style="width: 100px; height: 100px; background-color: red; position: absolute; top: 50px; left: 50px;"></div>
<p>Mouse position: <span id="mouse-position"></span></p>
<script>
const dragElement = document.getElementById("drag-element");
const mousePosition = document.getElementById("mouse-position");
dragElement.addEventListener("dragstart", function() {
// dragover イベントならドラッグ中のカーソルの位置が FireFox でも取得できる
// window に dragover イベントを登録しておくことで画面中のどこにカーソルがあってもカーソルの位置を取得できる
window.addEventListener("dragover", handleDragover);
function handleDragover(event) {
const currentMouseX = event.clientX;
const currentMouseY = event.clientY;
mousePosition.innerHTML = "X: " + currentMouseX + ", Y: " + currentMouseY;
}
// dragend イベントで dragstart した時に追加したイベントハンドラーを掃除する
dragElement.addEventListener("dragend", dragCleanUp);
function dragCleanUp() {
window.removeEventListener('dragover', handleDragover);
dragElement.removeEventListener('dragend', dragCleanUp);
}
});
</script>
</body>
</html>
ドラッグ開始時に window に対して dragover イベントをつけることで画面のどこでも dragover が発生する様にし、dragover イベントの中で clientX, clientY を参照してマウスの位置を取得します。
こんな感じでFirefoxでもMicrosoft EdgeやGoogle Chromeと同様にドラッグ操作中にマウスの位置を取得でき、ブラウザ間の差異を吸収できます。