デスクトップアプリライクな操作性を実現するドラッグ&ドロップAPI
TIPS 061:ドラッグ&ドロップ時のスタイルを設定する
ドラッグ操作時に、操作中であることを視覚的に明確に示すため、ドラッグ元要素やドロップ領域のスタイルを変更することは、よく行われます。
以下では、dragstart/dragenter/dragleave/dropendなどのイベントを利用して、「ドラッグ時にドラッグ要素に枠線を付与し」、「ドロップ領域進入時に領域の背景色を変化」してみましょう。
[リスト03]ドラッグ元要素、ドロップ領域にスタイルを設定するコード(drop2.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>HTML5 TIPS</title>
<script>
window.addEventListener('DOMContentLoaded', function() {
// ドラッグ対象要素、ドロップ先要素を取得
var drag = document.querySelector('#drag');
var drop = document.querySelector('#drop');
// ドラッグ開始
drag.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('text', e.target.id);
// ドラッグ元要素に対して枠線を付与
this.style.border = 'solid 1px #f0f';
}, true);
// ドロップ領域に進入時
drop.addEventListener('dragenter', function(e) {
// ドロップ領域の背景を変更
this.style.backgroundColor = '#ff0';
e.preventDefault();
}, true);
// dragoverイベントをキャンセル
drop.addEventListener('dragover', function(e) {
e.preventDefault();
}, true);
// ドロップ領域から外れた時
drop.addEventListener('dragleave', function(e) {
// ドロップ領域の背景を元に戻す
this.style.backgroundColor = '#ffc';
e.preventDefault();
}, true);
// ドラッグ操作を終えた時
drag.addEventListener('dragend', function(e) {
// ドラッグ元要素から枠線を外す
this.style.borderStyle = 'none';
e.preventDefault();
}, true);
// ドロップ時
drop.addEventListener('drop', function(e) {
var id = e.dataTransfer.getData('text');
e.currentTarget.appendChild(document.getElementById(id));
e.preventDefault();
}, true);
});
</script>
</head>
<body>
<img id="drag" src="wings.jpg" draggable="true" />
<div id="drop" style="background-color:#ffc; width:450px; height:200px;"></div>
</body>
</html>
操作自体は、ごく単純です。dragstart/dragendイベントでドラッグ元要素の枠線を、dragenter/dragleaveイベントでドロップ領域の背景色を、それぞれ操作しています。
TIPS 062:他のアプリからテキストデータを受け取る
ドラッグ&ドロップできるのは、ブラウザ(ページ)内部の要素ばかりではありません。他のアプリからドラッグしたテキストやファイルを取得し、ブラウザ内部で処理することもできます。
例えば以下は、外部のアプリで選択したテキストをブラウザ上の決められた領域にドロップする例です。ドロップされたテキストは、そのまま領域内部に表示します。
[リスト04]外部のアプリから選択テキストをドラッグ&ドロップするコード(otherDrop.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>HTML5 TIPS</title>
<script>
window.addEventListener('DOMContentLoaded', function() {
// ドロップ先要素を取得
var drop = document.querySelector('#drop');
// ドロップ時の処理を定義
drop.addEventListener('drop', function(e) {
// 他のアプリから渡されたテキストを取得
var msg = e.dataTransfer.getData("text/plain");
// 取得したデータをページに反映
drop.textContent = msg;
e.preventDefault();
}, true);
// dragoverイベントをキャンセル
drop.addEventListener('dragover', function(e) {
e.preventDefault();
}, true);
});
</script>
</head>
<body>
<div id="drop" style="background-color:#ffc; width:450px; height:200px;"></div>
</body>
</html>
外部のアプリからデータを受け取るには、DataTransferオブジェクトのgetDataメソッドに、受け取るデータの種類を指定します(1)。指定できるデータの種類には、以下のようなものがあります。
表4:指定できるデータの種類(getDataメソッドの引数)
設定値
概要
text/plain
平のテキスト
text/html
HTML文字列
text/xml
XML文字列
text/uri-list
URI、ファイル名のリスト
ここでは、「text/plain」を指定していますので、ドロップされたデータを平のテキストとして取得します。ここではtextContentプロパティで、取得したテキストをそのままページに反映させていますが、例えばカンマ区切りテキストなどを取得して、これをテーブルとして加工するようなことも可能です。
TIPS 063:ファイルをドラッグ&ドロップする
ドラッグ&ドロップ APIでは、ブラウザの外部からファイルを受け渡しすることもできます。例えば以下は、前回のTIPS55のサンプルを(ファイル入力ボックスではなく)ドラッグ&ドロップでファイルを受け渡せるように書き換えたものです。
[リスト05]ドラッグ&ドロップでファイルを指定(otherDropFile.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>HTML5 TIPS</title>
<script>
window.addEventListener('DOMContentLoaded', function() {
// ドロップ先要素を取得
var drop = document.querySelector('#drop');
// ドロップ時の処理を定義
drop.addEventListener('drop', function(e) {
// ドロップされたファイルを取得(1)
var f = e.dataTransfer.files[0];
// ファイルの読み込みに成功したら、その内容を<img id="result">に反映
var reader = new FileReader();
reader.addEventListener('load', function() {
document.querySelector('#dropped').src = reader.result;
}, false);
// ファイルをData URL形式で取得
reader.readAsDataURL(f);
e.preventDefault();
}, true);
// dragoverイベントをキャンセル
drop.addEventListener('dragover', function(e) {
e.preventDefault();
}, true);
});
</script>
</head>
<body>
<div id="drop" style="background-color:#ffc; width:450px; height:200px;">
<img id="dropped" />
</div>
</body>
</html>
ポイントとなるのは、実に(1)の一点のみです。ドラッグ&ドロップされたファイルは、DataTransferオブジェクトのfilesプロパティでアクセスできます。filesプロパティの戻り値はFileオブジェクトですので、あとはそのままFileReaderオブジェクトのreadAsXxxxxメソッドに引き渡すことが可能です。FileReaderオブジェクトに関する詳細は、前回の記事も合わせて参照してください。
TIPS 061:ドラッグ&ドロップ時のスタイルを設定する
ドラッグ操作時に、操作中であることを視覚的に明確に示すため、ドラッグ元要素やドロップ領域のスタイルを変更することは、よく行われます。
以下では、dragstart/dragenter/dragleave/dropendなどのイベントを利用して、「ドラッグ時にドラッグ要素に枠線を付与し」、「ドロップ領域進入時に領域の背景色を変化」してみましょう。
[リスト03]ドラッグ元要素、ドロップ領域にスタイルを設定するコード(drop2.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { // ドラッグ対象要素、ドロップ先要素を取得 var drag = document.querySelector('#drag'); var drop = document.querySelector('#drop'); // ドラッグ開始 drag.addEventListener('dragstart', function(e) { e.dataTransfer.setData('text', e.target.id); // ドラッグ元要素に対して枠線を付与 this.style.border = 'solid 1px #f0f'; }, true); // ドロップ領域に進入時 drop.addEventListener('dragenter', function(e) { // ドロップ領域の背景を変更 this.style.backgroundColor = '#ff0'; e.preventDefault(); }, true); // dragoverイベントをキャンセル drop.addEventListener('dragover', function(e) { e.preventDefault(); }, true); // ドロップ領域から外れた時 drop.addEventListener('dragleave', function(e) { // ドロップ領域の背景を元に戻す this.style.backgroundColor = '#ffc'; e.preventDefault(); }, true); // ドラッグ操作を終えた時 drag.addEventListener('dragend', function(e) { // ドラッグ元要素から枠線を外す this.style.borderStyle = 'none'; e.preventDefault(); }, true); // ドロップ時 drop.addEventListener('drop', function(e) { var id = e.dataTransfer.getData('text'); e.currentTarget.appendChild(document.getElementById(id)); e.preventDefault(); }, true); }); </script> </head> <body> <img id="drag" src="wings.jpg" draggable="true" /> <div id="drop" style="background-color:#ffc; width:450px; height:200px;"></div> </body> </html>
操作自体は、ごく単純です。dragstart/dragendイベントでドラッグ元要素の枠線を、dragenter/dragleaveイベントでドロップ領域の背景色を、それぞれ操作しています。
TIPS 062:他のアプリからテキストデータを受け取る
ドラッグ&ドロップできるのは、ブラウザ(ページ)内部の要素ばかりではありません。他のアプリからドラッグしたテキストやファイルを取得し、ブラウザ内部で処理することもできます。
例えば以下は、外部のアプリで選択したテキストをブラウザ上の決められた領域にドロップする例です。ドロップされたテキストは、そのまま領域内部に表示します。
[リスト04]外部のアプリから選択テキストをドラッグ&ドロップするコード(otherDrop.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { // ドロップ先要素を取得 var drop = document.querySelector('#drop'); // ドロップ時の処理を定義 drop.addEventListener('drop', function(e) { // 他のアプリから渡されたテキストを取得 var msg = e.dataTransfer.getData("text/plain"); // 取得したデータをページに反映 drop.textContent = msg; e.preventDefault(); }, true); // dragoverイベントをキャンセル drop.addEventListener('dragover', function(e) { e.preventDefault(); }, true); }); </script> </head> <body> <div id="drop" style="background-color:#ffc; width:450px; height:200px;"></div> </body> </html>
外部のアプリからデータを受け取るには、DataTransferオブジェクトのgetDataメソッドに、受け取るデータの種類を指定します(1)。指定できるデータの種類には、以下のようなものがあります。
表4:指定できるデータの種類(getDataメソッドの引数)
設定値 | 概要 |
---|---|
text/plain | 平のテキスト |
text/html | HTML文字列 |
text/xml | XML文字列 |
text/uri-list | URI、ファイル名のリスト |
ここでは、「text/plain」を指定していますので、ドロップされたデータを平のテキストとして取得します。ここではtextContentプロパティで、取得したテキストをそのままページに反映させていますが、例えばカンマ区切りテキストなどを取得して、これをテーブルとして加工するようなことも可能です。
TIPS 063:ファイルをドラッグ&ドロップする
ドラッグ&ドロップ APIでは、ブラウザの外部からファイルを受け渡しすることもできます。例えば以下は、前回のTIPS55のサンプルを(ファイル入力ボックスではなく)ドラッグ&ドロップでファイルを受け渡せるように書き換えたものです。
[リスト05]ドラッグ&ドロップでファイルを指定(otherDropFile.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { // ドロップ先要素を取得 var drop = document.querySelector('#drop'); // ドロップ時の処理を定義 drop.addEventListener('drop', function(e) { // ドロップされたファイルを取得(1) var f = e.dataTransfer.files[0]; // ファイルの読み込みに成功したら、その内容を<img id="result">に反映 var reader = new FileReader(); reader.addEventListener('load', function() { document.querySelector('#dropped').src = reader.result; }, false); // ファイルをData URL形式で取得 reader.readAsDataURL(f); e.preventDefault(); }, true); // dragoverイベントをキャンセル drop.addEventListener('dragover', function(e) { e.preventDefault(); }, true); }); </script> </head> <body> <div id="drop" style="background-color:#ffc; width:450px; height:200px;"> <img id="dropped" /> </div> </body> </html>
ポイントとなるのは、実に(1)の一点のみです。ドラッグ&ドロップされたファイルは、DataTransferオブジェクトのfilesプロパティでアクセスできます。filesプロパティの戻り値はFileオブジェクトですので、あとはそのままFileReaderオブジェクトのreadAsXxxxxメソッドに引き渡すことが可能です。FileReaderオブジェクトに関する詳細は、前回の記事も合わせて参照してください。
デスクトップアプリライクな操作性を実現するドラッグ&ドロップAPI
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- HTML5のドラッグ&ドロップAPI、File API、Web Storage
- JavaScriptでローカルファイルを自在に操る- File API
- プラグインは要らない!音声/動画対応したHTML5- / 要素
- スマホアプリ開発にも便利な位置情報API- Geolocation API-
- クッキーより便利になったブラウザ標準ストレージ- Web Storage
- HTML+JavaScriptだけでブラウザに図形描画- Canvas API-
- サンプルのプログラムコード解説
- HTML+JavaScriptだけでブラウザに図形描画(3)- Canvas API-
- HTML+JavaScriptだけでブラウザに図形描画(2)- Canvas API-
- 「TAURI」で「丸アートお絵描き」アプリを作ろう