"BOKU"のITな日常

BOKUが勉強したり、考えたことを頭の整理を兼ねてまとめてます。

素のJavaScript(Vanilla JS)でドラッグ&ドロップを実装する

f:id:arakan_no_boku:20210508152042p:plain

目次

今回はサンプルとして、簡単なHTMLでドラッグエリアを作り、そこにドロップされたファイル名を取得して表示する・・というだけのものにします。

HTMLソース

ソースです。

<!DOCTYPE html>
<html lang="jp">
	<head>
		<!-- Required meta tags -->
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
		<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css" />
		<link rel="stylesheet" href="css/dragdrop.css"></link>
		<title>動作確認</title>
	</head>
	<body>
		<h3>動作確認用のテンプレート</h3>
		<table>
			<tr>
				<td>
					<div id="dragandrophandler" draggable="true">ここにファイルをドロップ</div>
				</td>
			</tr>
			<tr>
				<td>
					<input type="text" id="dropedfile" />
				</td>
			</tr>
		</table>
		<script type="text/javascript" src="js/dragdrop.js"></script>
	</body>
</html>

CSSは、クラス指定が必要ないnew.cssを使ってます。

newcss.net

不要な場合は以下の2行を消せばいいです。

<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css" />

ドラッグエリアのCSS

ドラッグエリアを少し広めにするために、CSSで定義しています。

#dragandrophandler {
	border: 2px dotted #0b85a1;
	width: 500px;
	height: 100px;
	color: #92aab0;
	text-align: left;
	vertical-align: middle;
	padding: 10px 10px 10 10px;
	margin-bottom: 10px;
	font-size: 200%;
}

ドロップエリアの定義のみです。

ドラッグ&ドロップのJavaScript

ファイル名は「dragdrop.js」です

var obj = document.getElementById("dragandrophandler");
obj.addEventListener(
	"dragenter",
	function (e) {
		e.stopPropagation();
		e.preventDefault();
		this.style.border = "2px solid #0B85A1";
	},
	false
);
obj.addEventListener(
	"dragover",
	function (e) {
		e.stopPropagation();
		e.preventDefault();
		document.getElementById("dragandrophandler").style.backgroundColor = "#ffffe0";
	},
	false
);
obj.addEventListener(
	"drop",
	function (e) {
		this.style.border = "2px dotted #0B85A1";
		e.preventDefault();
		var files = e.dataTransfer.files;
		document.getElementById("dropedfile").value = files[0].name;
		document.getElementById("dragandrophandler").style.backgroundColor = "#ffffff";
	},
	false
);
document.addEventListener(
	"dragenter",
	function (e) {
		e.stopPropagation();
		e.preventDefault();
		document.getElementById("dragandrophandler").style.backgroundColor = "#ffffff";
	},
	false
);
document.addEventListener(
	"dragover",
	function (e) {
		e.stopPropagation();
		e.preventDefault();
		obj.style.border = "2px dotted #0B85A1";
	},
	false
);
document.addEventListener(
	"drop",
	function (e) {
		e.stopPropagation();
		e.preventDefault();
	},
	false
);

objがドロップするDivタグのエリアを指しています。

エリアにはいってきたり(dragenter)、領域内にいたり(dragover)、ドロップされたり(drop)の処理をイベントとして拾って処理をします。

objの中だけの処理しか書いていないと片手落ちなので、領域の外の動作もdocumentに対してドラッグ領域外のイベント処理を書いてます。

ドロップ可能領域上にいるかどうかをわかりやすくするため、領域にはいってきたら薄い黄色の背景にして、でたら白に戻すみたいにしてます。 

動作確認します

フォルダ構成は、HTMLのあるフォルダに「js」「css」のサブフォルダがあって、そこにJavaScriptcssを置いている想定です。

テストの際はローカルにWEBサーバーをたてて、http://localhost・・のようにURLを指定して動かすようにしてください。

昔と違って、HTMLをダブルクリックして動かした場合の制約がどんどん厳しくなっているので、JavaScriptのテストはうまくいきません。

(そもそもCanvasAPIが動かないです)

動かすとこんな画面です。

 

f:id:arakan_no_boku:20210508194253p:plain

ドラッグ中は

f:id:arakan_no_boku:20210508194541p:plain

ドロップすると。

f:id:arakan_no_boku:20210508194624p:plain

ちゃんとファイル名が表示されてます。

いけてますね。

ではでは。