アドインなしで実現可能! ドラッグ&ドロップを使いこなそう連載:人気順に説明する初めてのHTML5開発(2/2 ページ)

» 2011年09月13日 00時00分 公開
[ナオキ(監修:山田祥寛)WINGSプロジェクト(http://www.wings.msn.to/)]
前のページへ 1|2       

画像ファイルをドラッグ&ドロップでグループ分けする例

 以上を理解したうえで、次は、2つの領域間のドラッグ&ドロップを実施するサンプルを作成してみよう。

 領域間のドラッグ&ドロップは、例えば、アップロード済みの画像ファイルをドラッグ&ドロップでグループ分けするアルバム・アプリケーションや、画像とひも付いたプロファイル情報などをグループ分けするSNSなどのアプリケーションなどで利用できるだろう。 なお、ここではsetDragImageメソッドを使用し、ドラッグ中にドラッグ元の画像を表示するようにしている。これにより、ドラッグ画像を視認できるため、ドラッグ・ミスを防止できるようになるが、現時点でsetDragImageメソッドを実装しているブラウザはFirefox/Chrome/Safariと多少制限される点に注意が必要だ。 実行結果は、以下のとおりだ。サンプルを実行すると、3つの領域が表示される。上の領域に表示された画像をドラッグ&ドロップで、下の動物アルバム、食べ物アルバムに移動させることができる。下の領域から上の領域に戻すことも可能だ。

図3 ドラッグ実行例

図4 右下の食べ物アルバム部分にハンバーガーの画像をドラッグ中(ハンバーガーの画像が左上にも表示され続ける)

図5 ドロップ結果

 それでは具体的なコードを見てみよう。

写真を該当のアルバムにドラッグ&ドロップでグループ分けできます。
<!-- (1)ドラッグ元とドラッグ先の要素にイベントや属性を指定 -->
<div id="drop" style="width:700px; height:260px; background-color:green; padding:10px;"
  ondragover="DragOver(event)" ondrop="Drop(event)" draggable="false">
  <img id="cat1pic" src="cat1.jpg" draggable="true" ondragstart="DragStart(event)" />
  <img id="hambpic" src="ハンバーガー.jpg" draggable="true" ondragstart="DragStart(event)" />
  <img id="hotpic" src="ホットケーキ.jpg" draggable="true" ondragstart="DragStart(event)" />   
</div>
動物アルバム
<div id="drop" style="width:340px; height:260px; background-color:blue; padding:10px;"
  ondragover="DragOver(event)" ondrop="Drop(event)" draggable="false">
</div>

食べ物アルバム
<div id="drop" style="width:340px; height:260px; background-color:purple; padding:10px;"
  ondragover="DragOver(event)" ondrop="Drop(event)" draggable="false">
</div>

<script type="text/javascript">

  // (2)ドラッグ開始時にデータの値を設定し、ドラッグ元の画像をドラッグ中に表示する
  function DragStart(event) {
    var img = document.getElementById(event.target.id);
    event.dataTransfer.setData("text", event.target.id);
    if (event.dataTransfer.setDragImage) {
      event.dataTransfer.setDragImage(img, 128, 128);
    }
  }

  ……省略……
</script>

アイコン・イメージを要素間でドラッグ&ドロップするサンプル(dnd2.htm

 領域間のドラッグ&ドロップの実装に追加するのは、関数ではなく、要素とその属性指定だけだ。setDragImageメソッドはドラッグ開始時にドラッグ元のイメージ要素を指定して利用するため、DragStart関数内に処理を記述する。

(1)ドラッグ元とドラッグ先の要素にイベントや属性を指定

 ドラッグ元とドラッグ先の要素にイベントや属性を指定する。ドラッグ元とドロップ先を明確にするために<div>要素に幅、高さ、背景色(ドラッグ先とドロップ先の違いは背景色のみ)を指定している。後は、画像ファイルを追加し、それぞれにdraggable属性を追加している。

(2)ドラッグ開始時にドラッグ元要素のID値を設定し、ドラッグ元の画像をドラッグ中に表示する

 setDataメソッドでドラッグ元要素のID値を追加している点は、先ほどのサンプルと同じだ。それに追加して、今回はsetDragImageメソッドを追記している。setDragImageメソッドは第1パラメータに<img>要素のDOMオブジェクトを指定する。今回はドラッグ元の画像のDOMオブジェクトを取得し、それを指定している。なお、第2、3パラメータは、ドラッグ中に表示されるアイコンの座標を意味する。

■ほかのブラウザや別タブのデータをドラッグ&ドロップで受け取る

 現在の仕様では、HTML5のDrag and Drop APIはMIMEタイプを指定することでほかのブラウザや別タブのデータ、さらにはローカル・ファイルのドラッグ&ドロップを実行できる。対応しているMIMEタイプは以下のとおりだ。

MIMEタイプ 概要
text/plain プレーン・テキスト・データ
text/html HTML文字列
text/xml XML文字列
text/uri-list URIのリスト
ドロップ操作に関するイベント

 MIMEタイプはgetDataメソッドで指定する。実際にMIMEタイプを指定した場合のサンプルは図6〜7のようになる。

図6 ほかアプリケーションのドラッグ前

図7 ほかアプリケーションからのデータ渡し

 今回のサンプルではFirefoxとChrome間で値を受け渡しているが、ローカル・コンピュータからのファイルのドラッグ&ドロップも可能だ。それでは、実際のコードを見てみよう。

ドロップ領域
<div id="drop" style="width:700px; height:300px; padding:10px; border:3px solid" ondragover="onDragOver(event)" ondrop="onDrop(event)" ></div>

<script type="text/javascript">
var disp  = document.getElementById("disp");
function onDrop(event) {
  var text = event.dataTransfer.getData("text/plain");
  drop.innerHTML = text;
  event.preventDefault();
}
function onDragOver(event) {
    event.preventDefault();
}
</script>

ほかアプリケーション間のデータをドラッグ&ドロップするサンプル(dnd3.htm

 ここまでに触れてきたサンプルとの違いは、太字で記載されているgetDataメソッドの部分だけだ。MIMEタイプを参照することでドラッグ元を意識することなくドロップされたデータを取得できる。 このような仕組みを利用すれば、(例えば)ドラッグ&ドロップでファイルを指定できるアップロードのような仕組みも簡単に実装できるだろう。

■まとめ

 今回は、ブラウザ上でプラグインなしで実現できるドラッグ&ドロップについて解説した。あくまで一例だが、ドラッグ&ドロップの使用を少しでもイメージしてもらえれば幸いだ。今後、Webアプリケーションを構築する際には、必要に応じて直感的な操作性を実現するドラッグ&ドロップの実装を検討してみるとよいだろう。 ちなみに、本連載の第6回では、ローカル・ファイルからブラウザ上へドラッグ&ドロップする際にFiles APIとDrag and Drop APIの連携についても取り扱う予定だ。

 そして次回は、DOM操作を簡単に実現するためのセレクタAPIとCSSセレクタを紹介する。お楽しみに。

「連載:人気順に説明する初めてのHTML5開発」のインデックス

連載:人気順に説明する初めてのHTML5開発

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。