JavaScript入門[HTML5編]ドラッグ要素を移動する

  1. HOME
  2. JavaScript入門[HTML5編]
  3. ドラッグ要素を移動する

ここまで、ドラッグ要素をinnerHTMLで書き出し、複製する方法を見てきました。 ここでは、ドラッグ要素を移動する方法について見ていきましょう。

ドラッグ要素を移動するサンプルプログラム

ドラッグ要素を移動するには、appendChild()を使います。以下のように使います。

droparea.appendChild( dragObj )
ドラッグ要素dragObjを、ドロップされる要素dropareaに移動します。

このプログラムでは、2つの画像(AとB)を表示していますが、 そのうちAだけドラッグ&ドロップできるようになっています。 Aを下のエリアにドロップすると、上のエリアからAが消え、Bが左にスライドします。

<div class="dd" id="dragarea">
<img src="img/a.png" width="100" height="100" id="img1" alt="">
<img src="img/b.png" width="100" height="100" alt="">
</div>
<div class="dd" id="droparea"></div>

<style type="text/css">
div.dd{ width:100%; height:100px; }
div#dragarea{ background-color:#80ffff; }
div#droparea{ background-color:#ffff80; }
</style>

<script>
//ドラッグ要素とドロップエリアの取得
var obj1 = document.getElementById( "img1" );
var obj2 = document.getElementById( "droparea" );

//ドラッグ開始時の処理
obj1.addEventListener( "dragstart" , function(evt){

  //ドラッグ要素のidをdataTransferにセット
  evt.dataTransfer.setData( "text/plain" , evt.target.id );
  evt.stopPropagation();
}, false );

//ドロップされた時の処理
obj2.addEventListener( "drop" , function(evt){

  //id名をdataTransferから取り出す
  var id = evt.dataTransfer.getData( "text/plain" );

  var obj3 = document.getElementById( id );
  if( obj3 )
  {
    obj2.appendChild( obj3 );  //要素を移動する
  }

  evt.preventDefault();
}, false );

//2つのイベントでデフォルト動作を抑制する
obj2.addEventListener( "dragenter" , function(evt){
  evt.preventDefault();
}, false );
obj2.addEventListener( "dragover" , function(evt){
  evt.preventDefault();
}, false );
</script>

<サンプル>Aの画像を下にドラッグしてみてください。

サンプルコードの解説

では、上記のサンプルスクリプトの解説をしていきます。

HTML部分

<div class="dd" id="dragarea">
<img src="img/a.png" width="100" height="100" id="img1" alt="">
<img src="img/b.png" width="100" height="100" alt="">
</div>
<div class="dd" id="droparea"></div>

まずはHTML部分です。上側の列はドラッグする要素を表示する部分です。 divタグにid名「dragarea」を付け、中に画像を2つ表示しています。 今回はAの方だけドラッグするので、そちらのimgタグにだけid属性を付けています。 id名は「img1」にしました。

ドロップされるエリアのdivタグにはid名「droparea」を付けました。 また2つのdivタグにクラス名「dd」を付けているのは、後で共通のスタイルを指定するためです。

スタイルシート部分

<style type="text/css">
div.dd{ width:100%; height:100px; }
div#dragarea{ background-color:#80ffff; }
div#droparea{ background-color:#ffff80; }
</style>

続いてCSSを見てみます。最初はクラス名「dd」が付いたdivタグの横幅を100%、高さを100pxにしました。

また、id名「dragarea」が付いたdivタグの背景色を薄青に、 id名「droparea」が付いたdivタグの背景色を薄黄色に指定しています。

ID名の取得

var obj1 = document.getElementById( "img1" );
var obj2 = document.getElementById( "droparea" );

今度はスクリプト部分を見ていきます。 id名「img1」が付いたドラッグ要素と、 ドロップされる側のid名「droparea」をgetElementById()で取得し、変数obj1,obj2に格納しています。

ドラッグ開始時の処理

obj1.addEventListener( "dragstart" , function(evt){
  evt.dataTransfer.setData( "text/plain" , evt.target.id );
  evt.stopPropagation();
}, false );

まずはドラッグされる画像タグに、addEventListener()でdragstartイベントを追加しています。

イベントの内部で、ドラッグ要素のid名をdataTransferに渡します。 id名はtarget.idで取得します。

stopPropagation()はイベントの余計な伝播を防ぐためのものです。

ドロップされた時の処理

obj2.addEventListener( "drop" , function(evt){
  var id = evt.dataTransfer.getData( "text/plain" );
  var obj3 = document.getElementById( id );
  if( obj3 )
  {
    obj2.appendChild( obj3 );
  }
  evt.preventDefault();
}, false );

ドロップされるエリアのdivタグには、addEventListener()でdropイベントを追加します。

イベント内部で最初にdataTransferからデータを取得し、変数idに格納します。 dataTransferに渡したデータはドラッグ要素のid名でした。

取得したid名とdocument.getElementById()を使ってドラッグ要素を特定し、 変数obj3に格納します。 if文でドラッグ要素を掴めたか確認し、 成功していたらappendChild()を使ってドラッグ要素をドロップします。 appendChild()を使うと、要素が移動することになります。

preventDefault()は、ブラウザのデフォルトの動作を抑制します。

2つのイベントでデフォルト処理を抑制する

obj2.addEventListener( "dragenter" , function(evt){
  evt.preventDefault();
}, false );
obj2.addEventListener( "dragover" , function(evt){
  evt.preventDefault();
}, false );

今までと同じですが、dragenterイベントとdragoverイベントでもブラウザのデフォルト動作を抑制します。