【Vanilla JS】要素をドラッグ&ドロップする方法

先日、地図にピン立てて位置情報を記憶する機能を実装する機会がありました。

その際にピンをドラッグ&ドロップさせる機能を素のJavaScriptで実装しましたのでその際の備忘録としてここに記します。

Vanilla JS … 素のJavaScriptのこと

動作サンプル

スクリプト

const DragHandler = {

	// privateプロパティ。
	_oElem: null,

	// publicメソッド。ドラッグハンドラーを要素にアタッチします。
	attach: function(oElem) {

		oElem.style.position = "absolute";

		oElem.onmousedown = DragHandler._dragBegin;

		// コールバック。
		oElem.dragBegin = new Function();
		oElem.drag = new Function();
		oElem.dragEnd = new Function();

		return oElem;
	},

	// privateメソッド。ドラッグ処理を開始します。
	_dragBegin: function(e) {
		const oElem = DragHandler._oElem = this;

		if (isNaN(parseInt(oElem.style.left))) {
			oElem.style.left = '0px';
		}
		if (isNaN(parseInt(oElem.style.top))) {
			oElem.style.top = '0px';
		}

		const x = parseInt(oElem.style.left);
		const y = parseInt(oElem.style.top);

		e = e ? e : window.event;
		oElem.mouseX = e.clientX;
		oElem.mouseY = e.clientY;

		oElem.dragBegin(oElem, x, y);

		document.onmousemove = DragHandler._drag;
		document.onmouseup = DragHandler._dragEnd;
		return false;
	},

	// privateメソッド。要素をドラッグ(移動)します。
	_drag: function(e) {
		const oElem = DragHandler._oElem;

		const x = parseInt(oElem.style.left);
		const y = parseInt(oElem.style.top);

		e = e ? e : window.event;
		oElem.style.left = x + (e.clientX - oElem.mouseX) + 'px';
		oElem.style.top = y + (e.clientY - oElem.mouseY) + 'px';

		oElem.mouseX = e.clientX;
		oElem.mouseY = e.clientY;

		oElem.drag(oElem, x, y);

		return false;
	},

	// privateメソッド。ドラッグ処理を停止します。
	_dragEnd: function() {
		const oElem = DragHandler._oElem;

		const x = parseInt(oElem.style.left);
		const y = parseInt(oElem.style.top);

		oElem.dragEnd(oElem, x, y);

		document.onmousemove = null;
		document.onmouseup = null;
		DragHandler._oElem = null;
	}

}

実行用サンプルコード

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>要素ドラッグアンドドロップ</title>
  <script type="text/javascript" src="drag.js"></script>
</head>
<body>
  <img src="pin.png" id="pin" width="60px">
  <script type="text/javascript">
var pin = document.getElementById("pin");
DragHandler.attach(pin);
  </script>
</body>
</html>

サンプルピン