以前にもjQueryを使ってドラッグでコンテンツ要素をスクロールさせるUIを紹介しましたが、ストレージサービスなどでたまに見かける、画像を特定のエリアにドラッグ&ドロップさせるUIの実験的サンプルを作ってみたのでここでも紹介してみます。

jQueryで画像をドラッグ&ドロップするUIを実装する実験

まずは動作のサンプルから。
下のサンプル画面上の画像はエリア下にある灰色のエリアにドロップすることができます。

ドラッグした画像は元のリストエリアにドラッグし直すことで元の位置に戻ります。
ドラッグエリア下にある「すべて選択」をクリックするとすべてドロップされた状態になり、「選択クリア」をクリックするとドラッグされた画像はすべてもとの位置に戻ります。

この動作の全体構成について、まずはHTMLから。

◆HTML
<div id="dragitemlist">
<ul class="draglist">
<li><span class="dragparts"><a href="#"><img src="img/photo01.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo02.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo03.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo04.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo05.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo06.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo07.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo08.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo09.jpg" width="100" height="100" alt="" /></a></span></li>
<li><span class="dragparts"><a href="#"><img src="img/photo10.jpg" width="100" height="100" alt="" /></a></span></li>
</ul>
</div><!--/#draglist-->

<div id="droparea"></div>

<div id="actionarea">
<a href="javascript:void(0);" id="allselect">>すべて選択</a> | <a href="javascript:void(0);" id="listclear">>選択クリア</a>
</div><!--/#actionarea-->

HTMLは画像を配置するリストに対してドラッグアイテムを配置してドラッグアイテムに対してはクラス「dragparts」を付加しています。

ドロップエリアはIDを付けた<div>エリアを配置しています。

これに対してのCSSは以下になります。

◆CSS
/* .dragparts / .dragparts_drop
--------------------------- */
.dragparts,
.dragparts_drop {
	top: 0;
	left: 0;
	width: 100px;
	height: 100px;
	display: inline-block;
	overflow: hidden;
	position: absolute;
}


/* #dragitemlist
--------------------------- */
#dragitemlist {
	margin-bottom: 50px;
	width: 525px;
	text-align: left;
	position: relative;
}

#dragitemlist ul.draglist {
	margin-left: 5px;
	width: 100%;
}

#dragitemlist ul.draglist li {
	margin: 0 5px 5px 0;
	width: 100px;
	height: 100px;
	display: inline;
	float: left;
	position: relative;
}


/* #droparea
--------------------------- */
#droparea {
	padding: 5px 0 0 5px;
	min-height: 100px;
	background: #ddd;
}

#droparea.areahover {
	background: #666;
}

#droparea .dragparts_drop {
	margin: 0;
	padding: 0 5px 5px 0;
	position: relative;
}


/* #actionarea
--------------------------- */
#actionarea {
	padding: 10px 0;
}

#allselect,
#listclear {
	padding: 0 10px;
}


/* =======================================
	ClearFixElements
======================================= */
#dragitemlist ul:after {
	content: ".";
	height: 0;
	clear: both;
	display: block;
	visibility: hidden;
}
#dragitemlist ul {
	display: inline-block;
}

CSSは特に大きな重要な項目はありませんが、ドラッグするアイテムは「position:absolute」にしておく必要があります。

そしてドラッグ&ドロップを実装するスクリプトは以下のように。

◆SCRIPT
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
<script type="text/javascript">
$(function(){
	$('ul.draglist li').each(function(i){

		// 制御用ナンバリング追加
		$(this).attr('id','list' + (i + 1).toString());
		$(this).children('span').attr('id','item' + (i + 1).toString());

		$(this).attr('rel',(i + 1).toString());
		$(this).children('span').attr('rel',(i + 1).toString());

		$(this).addClass('disposition');

		// 暗転画像クローン生成
		var imgClone = $(this).children('.dragparts').children('a').html();
		$(this).prepend('<span class="imgblank">' + (imgClone) + '</span>');
		$('.imgblank').css({top:'0',left:'0',position:'absolute',opacity:'0.2'});

		// 「.dragparts」をドラッグ
		dragParts();
		function dragParts(){
			$('.dragparts,.dragparts_drop').draggable({
				revert:'invalid',
				zIndex:'1000'
			});
		}

		// 「#droparea」エリアにドロップされた時の処理
		$('#droparea').droppable({
			accept: '.dragparts',
			tolerance: 'touch',
			hoverClass: "areahover",
			activate: function(ev, ui){
				var pos = ui.position;
			},
			drop: function(ev, ui){
				ui.draggable.prependTo(this).removeClass('dragparts').addClass('dragparts_drop').css({top:'0',left:'0'});
				dragParts();
			}
		});

		// 「#dragitemlist」エリアにドロップされた時の処理
		$('#dragitemlist').droppable({
			accept: '.dragparts_drop',
			tolerance: 'touch',
			drop: function(ev, ui){
				var thisRel = ui.draggable.attr('rel');
				var adjustRel = thisRel-1;
				$('.disposition').eq(adjustRel).each(function(){
					ui.draggable.appendTo(this).removeClass('dragparts_drop').addClass('dragparts').css({top:'0',left:'0'});
					dragParts();
				});
			}
		});

		var connectCont = $('ul.draglist li').index(this);
		var numCont = connectCont+1;

		// 「すべて選択」処理
		$('#allselect').click(function(){
			$('ul.draglist .dragparts').appendTo('#droparea').removeClass('dragparts').addClass('dragparts_drop');
		});

		// 「選択クリア」処理
		$('#listclear').click(function(){
			$('#item'+numCont).each(function(){
				var thisHTML = $(this);
				$('#list'+(numCont)).append(thisHTML);
				$('.dragparts_drop').addClass('dragparts').removeClass('dragparts_drop');
			});
		});
	});
});
</script>

ドラッグ&ドロップを実装するするにはjQueryライブラリファイルと併せて、「jquery-ui.js」を使用します。

ドラッグするアイテムに対しては
———————————
$(‘●●●●’).draggable();
———————————
でドラッグする処理の指示を与え、ドロップエリアに対しては
———————————
$(‘●●●●’).droppable();
———————————
にてドロップエリアの処理を指定します。

サンプルでは上下のドロップエリアで違う処理を行う必要がある為、ドロップされるごとにドラッグアイテムのクラスを入れ替える処理をしています。

ドラッグ処理とドロップ処理では数々のオプションを付けることができます。
細かなオプションやオブジェクトプロパティなどについては、下記のリファレンスサイトがとても参考になります。

・draggable();
Draggable – jQuery UI API 1.8.4 日本語リファレンス – StackTrace

・droppable();
Droppable – jQuery UI API 1.8.4 日本語リファレンス – StackTrace

今回のサンプルは単純なドラッグ&ドロップ処理になりますが、これを元にいろいろなドラッグ&ドロップのパターンのUIを試してみたいと思います。
(ちなみに今回のドラッグ&ドロップサンプルはiPhoneでは動作しません。。。)

jQueryでドラッグ&ドロップを使ったUIが必要になった際に是非。。。

サンプルファイルをダウンロードしたい方はこちらから

SHARE

Comments (5)

  • nkt | 2012.06.26 14:53

    いつも参考にさせていただいております、nktです。サンプルいじらせてもらっています。
    ドロップされた画像のxとyの値を取得したく、以下ソースを追加してみたのですがうまくいかず…
    できればドロップされた画像名も取得したいのですが…
    もしよろしければご回答いただけないでしょうか?

    // 「#droparea」エリアにドロップされた時の処理
    document.frm.left.value = dragParts.style.left;
    document.frm.top.value = dragParts.style.top;

  • nkt | 2012.06.27 18:27

    ドラッグされたエレメントのidは以下のソースで取得することができました。
    javascriptにあまり詳しくないので座標の取得方法はわかりませんでしたが…

    var data = ui.draggable.attr(“id”);
    alert(data);

    また、droparea内にドラッグしたときに現状top:0; left:0;となっていますが、
    自由な位置に配置することはできるんでしょうか?

    重ね重ねの質問で恐縮ですが、宜しくお願いします。

  • BlackFlag | 2012.06.28 0:36

    >nktさん

    コメントありがとうございます。

    ドロップされたアイテムの処理についてですが
    jQueryで座標をとる場合は「.offset()」を使うことで
    可能になるかと思います。

    「drop: function(ev, ui){」の中に
    —————————————–
    var offset = $(this).offset();
    alert(‘X:’ + offset.left + ‘,Y:’ + offset.top)
    —————————————–
    と追記することで、
    X座標とY座標を取得できるかと思います。

    ドロップされた際のアイテムの位置指定に関しては
    このサンプルではドロップされたアイテムは
    「position: relative;」にして整列する構成にしまっているので
    このままだとちょっと厳しいかもしれません。。

    また方法を思いついたらサンプルを用意してみます。。
    よろしくお願いします。

  • viora | 2012.07.02 10:17

    iPhoneなどのタッチデバイスで
    ドラッグ操作できないことへの対応は、
    やはりタッチで一度選択状態にして
    移動ボタンで実行というような方法しかできないでしょうか?

  • BlackFlag | 2012.07.02 23:12

    >vioraさん

    コメントありがとうございます。

    ご質問いただきました、iPhoneなどタッチデバイスでの
    ドラッグ操作を組み込むにはいろいろな方法がありますが、
    ここで紹介している「.draggable()」「.droppable()」を使って実現するには
    https://black-flag.net/jquery/20120509-3821.html
    こちらで紹介しているプラグインを使うことで実現できるかと思います。

    もしくは
    https://black-flag.net/jquery/20120306-3710.html
    こちらのスクリプトが参考になるかと思います。

    よろしくお願いします。







コメント内容

※コメントにHTMLタグを直接入力しないでください。
※HTMLタグを入力する際はタグ一つ一つの括弧「<」「>」を全角に変換して入力してください。

コメントは承認制になっているのですぐには反映されません。コメント頂いた内容については出来る限り早めの対応を心掛けていますが、時期によって返答が遅くなってしまうことがありますので、何卒ご了承ください。
» コメントについてのご注意  |  » ライセンスに関して