一から勉強させてください( ̄ω ̄;)

最下級エンジニアが日々の学びをアウトプットしていくだけのブログです。

要素をドラッグアンドドロップしてみた

今回はHTML5でサポートされたドラッグアンドドロップに挑戦しました。

あ、ちなみに以前書いたFile APIを使ったファイル読み込みと同じ本を参考にしてます。。
(今後もお世話になり続けることが予想されるので毎回紹介するといったことはしませんw)


では早速、サンプルについてなんですが、
今回は山田さん、田中さん、山本さんの3要素をドロップエリアにドラッグアンドドロップして、「◯◯さんがドラッグアンドドロップされましたよー」と表示するサンプルを作ってみました↓

http://jsfiddle.net/d_animal141/Sr6Nx/2/embedded/result/


あと、この文言の表示には前回書いたjsRenderを使用しています。


それではコードのほうを!!

<html> 
  <head> 
  <meta charset="utf-8">
  <title>ドラッグアンドドロップサンプル</title> 
  <style type="text/css">
.draggable {width: 100px; height: 40px; line-height:30px; margin: 10px; float: left; 
            text-align: center; background-color: blue; color: white;}
.droppable {width: 250px; height: 250px; padding:50px; margin-left:50px; border: inset 5px red; float: left;}
  </style>	
</head>
<body>
  <div draggable="true" class="draggable">山田さん</div>
  <div draggable="true" class="draggable">田中さん</div>
  <div draggable="true" class="draggable">山本さん</div>
  <div id="target" class="droppable">Drop here</div>

  <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
  <script src="http://borismoore.github.com/jsrender/jsrender.js"></script>
  <script type="text/javascript">

   $(".draggable").on("dragstart", function(event){
      //dataTransferオブジェクトのsetDataメソッドでドラッグするデータをセット
      event.originalEvent.dataTransfer.setData("Text", $(this).text());
   })

   $("#target").on("dragover", function(event){
      //デフォルトのイベントを無効にする
      event.preventDefault();
   })

   $("#target").on("drop", function(event){
    //デフォルトのイベントを無効にする
    event.preventDefault();
    var data = event.originalEvent.dataTransfer.getData("Text");
    $(this).html($("#data").render({data:data}));
   })

  </script>
  <script id="data" type="text/x-jsrender">
    <p>おーーっと{{:data}}がドラッグアンドドロップされましたよー</p>
  </script>
</body>
</html>


順番にみていきます。


まずHTML側では、対象となる3要素+ドロップするエリアをちょっとCSSで装飾しつつ用意しました。(クラス名は3要素共通でdraggableとしました)
ここで重要なのがdraggable属性!!ドラッグしたい要素にdraggable="true"を指定することで要素のドラッグが可能になります!!(ちなみにaとかimgはデフォルトでドラッグ可能)
                  ↓
次に先ほどの要素に対して、ドラッグ開始(dragstart)した時の動きを登録していきます。
ここでjQueryのeventオブジェクトはjQueryが独自に開発したものらしく、ドラッグアンドドロップに関するオブジェクトを持っていません。そこでまず、オリジナルのeventオブジェクトを取得する必要があります。これはevent.originalEventで取得できます。

で、そいつのdataTransgerオブジェクトのsetDataというメソッドにformatとdataをセットします。今回はformatがtext, dataはその要素のtext()で取得できます。
                  ↓
ドラッグされた要素がドロップエリアに移動する際に発生するイベント、dragoverを無効にしないと、うまくドロップの操作が動きませんでした。
(dragoverイベントは「ドラッグ・オペレーションを"none"にする」というデフォルトアクションを持っているらしいです…)

そこで、このイベントに対して、preventDefaultメソッドを使ってデフォルトの挙動を無効化します。
                  ↓
次にドロップエリアにドロップした際の動きを登録します。
こちらはなくても問題なかったのですが、まずdropイベントのデフォルトの挙動を上記と同様に無効化します。
そして、今度はdataTransferのgetDataメソッドで先ほどセットしたデータを取得します。

んで、このデータをjsrenderを使って、ドロップエリア内に表示します。
                  ↓
あとはjsrenderのテンプレートを書いておくだけでOK!


これで要素をドロップエリアにドラッグアンドドロップしたら、その要素名がエリア内に表示されるようになりました。


前回やったjsRenderの復習になったし、ドラッグアンドドロップの基本的な動きもわかったので、とても良いサンプルでした。
しかもdraggable="true"にしておくだけで、ドラッグができるようになり、あとはdataTransferのsetData,getDataメソッドでデータを渡すだけでOK。
直感的でわかりやすかったです!!

このドラッグアンドドロップは地味にいろんなところで必要になりそうやし、要チェックですな。がんばろー


小さなことからコツコツと。