script.aculo.usを読み解く

第11回 dragdrop.js (前編)

この記事を読むのに必要な時間:およそ 8.5 分

JavaScriptでドラッグ&ドロップを実現するためのライブラリ,dragdrop.jsを,3回に分けて解説していきます。

昨今,メールクライアントなど,これまでデスクトップにあったものがブラウザの上で動くようになりました。それによって,"外出先でも使える""インストール作業がいらない"などの利点はあるものの,GUIとしては退化してしまった感があります。

ドラッグ&ドロップという操作は,物を運んだり,他の場所に置くといった,人間の行動を直感的に表現していて,優れたGUIです。このライブラリを使えば,Webページをよりインタラクティブなものに変えていくことができるはずです。

0001:// script.aculo.us dragdrop.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
0002:
0003:// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
0004://           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
0005:// 
0006:// script.aculo.us is freely distributable under the terms of an MIT-style license.
0007:// For details, see the script.aculo.us web site: http://script.aculo.us/
0008:

1~8行目は著作権表示です。

0009:if(Object.isUndefined(Effect))
0010:  throw("dragdrop.js requires including script.aculo.us' effects.js library");
0011:

9~11行目で,dragdrop.jsはeffects.jsに依存しているので,effects.jsがロードされているかをチェックしています。

Droppables

ドラッグ&ドロップの,ドロップ先を記述したクラスです。このクラスの機能には,ドラッグが上空に来たときスタイルの変化でドロップを促したり,ドロップした瞬間にフックを呼んだり,ドロップを受け付けるかどうかを制限するといったものがあります。

このクラスにおいてoptionsは,変数名からはただオプション設定をまとめたものに思えますが,実はドロップ先の情報を一手に引き受けまとめている重要なオブジェクトになっています。実際,drops配列にこのoptionsを格納することからも,それがわかります。

ここでまとめて,このクラスに登場するプロパティの意味を解説します。

last_active
現在,ドラッグが上空にあるドロップ先です。マウスイベントで常に更新されます。
options.greedy
デフォルトはtrueです。まだ実装されていませんが,公式wikiの説明では,ドロップ先としてより貪欲に振る舞い,ドラッグが上空にきただけで強制的にドロップさせるオプションのようです。
options.hoverclass
デフォルトはnullです。クラス名が入ります。ドロップを受けつけるドラッグが上空にきたときに,ドロップ先の要素に指定したクラス名を追加するオプションです。例えば,このクラス名に要素を明るくするようなCSSを定義しておくことで,ユーザに,ドロップできることを視覚で伝えることができます。
options.tree
デフォルトはfalseです。後編で解説するSortableでドロップ先がツリーとして振る舞うときに,このオプションが重要になります。
options.containment
DOM idか,DOM idの配列を指定します。ここで指定した要素の子要素のドロップだけを受けつけます。
options._containers
内部的に使います。上述のcontainmentで指定したDOM idに$関数を適用した結果を,ここにキャッシュしておきます。
options.accept
DOM idか,DOM idの配列を指定します。ここで指定した要素のドロップだけを受けつけます。
options.element
内部的に使います。ドロップ先の要素です。
options.onHover
ドロップを受けつけるドラッグが上空にきたときに呼ぶフックです。このフックは引数に,ドロップ先の要素,ドラッグ中の要素,それらの位置の重なり具合,をとります。
options.onDrop
ドロップがあったときに呼ぶフックです。このフックは引数に,ドロップ先の要素,ドロップした要素,マウスイベントのイベントオブジェクト,をとります。

それではコードを見ていきましょう。

0012:var Droppables = {
0013:  drops: [],
0014:

12~14行目のdropsは,ドロップ先の情報をまとめたoptionsを,順番に格納するための配列です。

0015:  remove: function(element) {
0016:    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
0017:  },
0018:

15~18行目のremoveは,引数のドロップ先要素を,drops配列から削除する関数です。

0019:  add: function(element) {
0020:    element = $(element);
0021:    var options = Object.extend({
0022:      greedy:     true,
0023:      hoverclass: null,
0024:      tree:       false
0025:    }, arguments[1] || { });
0026:
0027:    // cache containers
0028:    if(options.containment) {
0029:      options._containers = [];
0030:      var containment = options.containment;
0031:      if(Object.isArray(containment)) {
0032:        containment.each( function(c) { options._containers.push($(c)) });
0033:      } else {
0034:        options._containers.push($(containment));
0035:      }
0036:    }
0037:    
0038:    if(options.accept) options.accept = [options.accept].flatten();
0039:
0040:    Element.makePositioned(element); // fix IE
0041:    options.element = element;
0042:
0043:    this.drops.push(options);
0044:  },
0045:

19~45行目のaddは,引数の要素を,ドロップ先としてdrops配列に追加する関数です。

31行目で,options.containmentがDOM idの配列で与えられた場合は,それぞれに$関数を適用して_containersに追加していきます。これはmap関数を使ってもよいでしょう。

33行目で,同様に,DOM idで与えられた場合も,$関数を適用して追加します。

38行目で,options.acceptには,DOM idの配列か,DOM idを与えることになっていますが,ここでDOM idの配列の形に統一します。そのためにいったん配列にしてflatten関数を呼びます。

40行目で,ドロップ先は移動する必要がないのですが,IEの仕様のため,ここでmakePositionedします。

43行目で,drops配列にoptionsを追加します。

著者プロフィール

源馬照明(げんまてるあき)

名古屋大学大学院多元数理科学研究科1年。学部生のときにSchemeの素晴らしさを知ったのをきっかけに,関数型言語の世界へ。JavaScriptに,ブラウザからすぐに試せる関数型言語としての魅力と将来性を感じている。

ブログ:Gemmaの日記

コメント

コメントの記入