この記事は、http://www.onextrapixel.com/の許可を得て、翻訳しています。一部変更して翻訳している部分もある場合があります。オリジナルの記事はここよりご覧いただけます。

これまでにもドラッグ&ドロップスタイルの開発は行われてきましたがjQueryを始めとするオープンソーススクリプトを手掛けるプログラマーの増加に伴い、古くからのやり方が激変していくのも至極当然のことなのかもしれません。JavaScript libraryは非常に適応性も高く、次世代のWEBに対応する為に様々な改善を案提供しています。

jquery drag and drop jQuery ドラッグ&ドロップをマスターする!

今回は自由自在に動かせる非常に動的なドラッグ&ドロップボックスのスクリプトをご紹介します。プロセス全体としてはjQueryの機能を搭載し、細かい部分でGeneral Public License v3のスクリプトを利用していきます。殆どのスクリプトが既述のものなので、大幅な時間短縮が可能かと思います。ちなみにこのドラッグ&ドロップライブラリのコードは今度もプロジェクトやアプリで再利用が可能ですよ。

コンテンツの下準備

まず手始めに小さなプロジェクトサイトを開発してみましょう。今回はindex.htmlの他にjsファイルとcssファイルを使用していきます。そして今後のプロジェクトに活用出来るように、また理解し易いように極めてシンプルなコーディングにしてあります。

下記が基本となるHTMLファイルです。ヘッダーにはメイン部分のjQuertyを引用することになるGoogle Codeサーバを含め、全部で3つのスクリプトが指定してあります。これによりページロード時のHTTPリクエスト削減につながるので、訪問者にとっての時間短縮など負担を軽減させることが出来ます。それからドキュメントに基本的なレイアウトを施す為のstyle.cssファイルも指定してあります。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>DragnDrop Demo</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="js/jquery.dragndrop.js"></script>
    <script type="text/javascript" src="js/fn.js"></script>
    <link type="text/css" rel="stylesheet" href="css/style.css" />
</head>

<body>
<div class="dv1">
    <h2 class="handler">Drag me</h2>
    <div class="content">Yes, it is.</div>
</div>

<div class="dv2"><div class="gb">
    <h2 class="handler2">Drag me too</h2>
    <div class="content2">{ zIndex: 200, opacity: .9 }<br /><br /><small><strong>P.S. you can drag me from anywhere!</strong></small></div>
</div></div>

</body>
</html>

ボディ部分は2つのDIVタグで大分していて、それぞれドロップボックスを含有しています。コードは比較的単純で、どの部分が何に使用されるのか一目瞭然なのではないかと思います。ボックス内にはそれぞれ「handler」クラスと「handler2」クラスを付けたH2タグが既述されています。ボックスの動作は個々に異なるので、ドラッグして関数が呼び出された時にこのクラス名が重要になってきます。

google code homepage jQuery ドラッグ&ドロップをマスターする!

CSSスタイリング

HTMLはとてもシンプルなものにしたので、そんなに時間を取られることもなかったのではないでしょうか。基本的なマークアップ言語をご存知ならばCSSの方も余裕だと思います。今回は複雑なスタイリングはせず、大体が個々のパディングやマージン、色の指定をしているだけです。

body,html { font-family:Calibri, sans-serif; background:#eaf3fb; font-size:12px; height:1000px; line-height:18px; }
p { height:30px; }

こちらの「body,html」セレクタはデモページ用です。インデックスファイル内にはドラッグ用のボックスが2つあるだけなので、見栄えがよくなるようにしています。またこうすることによりCSSプロパティはデザインフィールを残したままスリム化することが出来ます。

.dv1 { width:200px; background-color:#eff7ff; border:1px solid #96c2f1; position:absolute; left:100px; top:100px; }
.dv1 h2 { background-color:#b2d3f5; padding:5px; font-family:Georgia, "Times New Roman", Times, serif; font-size:1.0em; text-transform:uppercase; font-weight:bold; color:#3a424a; margin:1px; cursor:move; }
.dv1 div { padding:5px; margin-bottom:10px; }
.dv2 { background-color:#f6ebfb; border:1px solid #a36fde; width:550px; position:absolute; cursor:move; left:400px; top:230px; }
.dv2 h2 { background-color:#eacfe9; letter-spacing:-0.09em; font-size:1.8em; font-weight: bold; padding:15px; margin:1px; color:#241f24; cursor:move; }
.dv2 .content2 { padding:5px; margin-bottom:10px; }

「.dv1」クラスと「.dv2」クラスでは絶対配置指定させています。本当はこうする必要もないかもしれませんし、こうしない方がいいのかもしれません。けれど今回のデモではページをリロードした時に元の場所に戻ってくれるので、これでいいのではないかと思います。それと、2つのクラス間でフォントサイズとパディング幅が異なるのにもお気付きいただけるのではないかと思います。2つのボックスをはっきり区別する為にこういう工夫がしてあります。

この他にはDIVタグ内部やH2タグは大体同じです。もし今回のコードをコピペして使用したい場合は、実行する前に1つ1つ名前など確認してから使ってくださいね。ドラッグ用のボックスが重複しないように、クラスではなくてIDを使用した方が賢い方法と言えるかもしれませね。

JavaScriptの解説

これらのボックスがうまく動作する為に必要なコードは、2つのJavaScriptファイルに全て含まれています。本日はちょっと本来の目的から外れてしまうのでjQueryの生のコードの詳細説明まではしないでおきますね。1つ目に注目したいファイルは「jquery.dragndrop.js」です。

このファイルの中に関数が幾つかありますが、中でも需要なのは22列目のDragsです。

$.fn.Drags = function(opts) {
    var ps = $.extend({
        zIndex: 20,
        opacity: .7,
        handler: null,
        onMove: function() { },
        onDrop: function() { }
    }, opts);

ここではDrags用の戻り変数を設定しており、また初期データ型も設定しています。こうすると他の関数とオプションをやりとりする時にコード内でのスペースを節約出来るので、jQuery開発者間でよく用いられる手法です。内部ではドラッグボックス間でやりとりされる可能性のある各オプションを拡張する為の変数を設定しています。

jquery extend documentation jQuery ドラッグ&ドロップをマスターする!

それに続けて変数「dragndrop」用に設定した2つのイベントハンドラ関数が記述されています。イベントパラメータが渡されると「drag」も「drop」も関数としてコールされます。このイベントはドラッグしようとボックスをクリックする時と、リリースした時に発生します。

var dragndrop = {
    drag: function(e) {
        var dragData = e.data.dragData;
        dragData.target.css({
            left: dragData.left + e.pageX - dragData.offLeft,
            top: dragData.top + e.pageY - dragData.offTop
        });
        dragData.handler.css({ cursor: 'move' });
        dragData.target.css ({ cursor: 'move' });
        dragData.onMove(e);
    },
    drop: function(e) {
        var dragData = e.data.dragData;
        dragData.target.css(dragData.oldCss); //.css({ 'opacity': '' });
        dragData.handler.css('cursor', dragData.oldCss.cursor);
        dragData.onDrop(e);
        $().unbind('mousemove', dragndrop.drag)
            .unbind('mouseup', dragndrop.drop);
    }
}

これで関数が各オブジェクトのCSSポジショニングを操作しているのを確認することが出来ます。JavaScript関数は定義済みのスタイルも上書きしてしまうので、絶対配置外に変更されてもボックスには影響を与えません。あとは関数のハンドラを確認したり、お化粧用のスタイル変更用コードなどが書かれています。具体的には透過度の低減、フォントスタイルや色、新規段落の追加などです。

生のDrag/Drop関数

2つ目のファイル「fn.js」はそんなに複雑ではありません。コア関数をコールする為のオブジェクトやドキュメントの読込が完了したらjQueryを介してチェックしています。先ほど既に取り上げたDrags関数のインスタンスを2つ定義しています。

「.dv1」と「.dv2」クラスを含んだ2つのブロックがありますよね。もしドラッグ可能なボックスは1つだけでよかったら、スペースを確保する為にも後半のコードは削除してしまってください。また新しいボックスを追加しても構いませんが、新しい関数をこのファイル内に設定する必要があります。

初めにセットするのは先に取り上げた変数名に基づいたオプションです。定義それぞれで最も重要なのはハンドラ名を設定することです。ハンドラ名は文書内の特定個所をクリックするかリリースした時にjQueryにイベントハンドラを伝える為に使用されます。クラスやIDでも構いませんし、DOM指向でもあなたのやり易い方法で大丈夫です。

1つめの関数内に、「onMove」と「onDrop」という2つのイベントハンドラがありますよね。両方とも変数「e」として現在のイベントに渡す新しい関数をコールします。そのあとはボックスが動くたびに、HTMLの内部を操作して変更しています。これはシンプルなjQueryイベントを使ってどれだけコントロールすることが出来るのか実証するのに一役買っていると思いますよ。

jquery written model1 577x323 jQuery ドラッグ&ドロップをマスターする!

2つめの関数はプロパティもとても少なくて、「zIndex」と「opacity」を呼び出しているだけです。もしいろいろ追加する時は、プロパティ設定をチェックするために先述のJavaScriptファイルも編集する必要がありますのでお気をつけくださいね。一例としてはどっちのボックスが移動しているかによって、フォントスタイルや高さ・幅の変数を渡すことが出来たりします。結構面白いですよ。

終わりに・・・

オープンソースコードにちょっと手を加えるだけで、こんなに面白いドラッグアンドドロップインターフェースを開発することが出来ます。jQueryはせっかちな開発者にも膨大なベネフィットを提供してくれており、のバックエンドインターフェースはデータを定義する新しい方法も示しています。

というのも、イベントベースの関数だけではなくてドラッグボックス間で新しい変数やりとりさせていますよね。これは様々な可能性を示唆していると思いますよ。今回のデモではこのコードを使ってどんなことが出来るのか簡単なアイデアを提供しているに過ぎません。もしもっと深く探求してみたくなったら、jQuery Documentationをみてみてくださいね。