Drag and Drop

Yahoo Developer Networkも機嫌を直したようなので、Drag and Drop(DD)のサンプリング。
DDのトップページを概観。

まず、使用するjsファイルは、

<!-- Dependencies --> 
<script type="text/javascript" src="scripts/yahoo-dom-event/yahoo-dom-event.js" >
</script>

<!-- Drag and Drop source file --> 
<script type="text/javascript" src="scripts/dragdrop/dragdrop-min.js" >
</script>

とのこと(YUIを使うDocument Root下に、scriptsというディレクトリを作って、ダウンロードしたYUIライブラリのbuild下を配備したと想定)

  • yahoo-dom-event/yahoo-dom-event.js

は、DomとEvent(という基本モジュール)をまとめたもののようだ。

基本形としては

var dd1 = new YAHOO.util.DD("element_id");

で、YAHOO.util.DDをnewすることで、コンストラクタに指定したidの要素が、Draggable(つまり、Drag and Dropできるように)になる。コンストラクタのシグナチャとしては、単なるelement(オブジェクト)も認められていて、サンプルとして、

var el=YAHOO.util.Dom.get("element1");
var dd1 = new YAHOO.util.DD(el);

が挙げられている。
Drag and Dropの機能自体は、Styleの変更によって行われるから、html上に書かれている要素自体にはなんら影響がないと書いてある。

ということで、主役はYAHOO.util.DDであるが、そのほか

YAHOO.util.DDProxy Draggableにしたオブジェクトの代理として、Drag and Dropされ、Drop後に消ええてしまう
YAHOO.util.DDTarget Draggableなオブジェクトと交差(interact)したり、それをDropされたりするが、それ自身はDraggableでない要素

の2つがあるようだ。

それ以下には、Drag and Drop Manager(pageスコープ内のsingletonと書いてあるので、page内でDDを発生させたときに、その動きの全てのコンフィグレーションを握るのだろう)、と、Interaction Groupという概念が紹介されている。
Drag and Dropによるイベント発生は、ひとつのInteractionグループ内のメンバーが交差(Interact)した際に発火するとのこと。DDをnewする際の引数として、このグループを指定できるが、指定しない場合はデフォルトグループ(全部同じグループ)となるそうだ。

しばらく下にいくと、重要なイベントについてかかれている。

イベント 意味
onMouseDown マウスが押されたタイミング(必ずしもDragを始めるタイミングではない)
startDrag マウスが押されて、Drag threshold(ドラッグを始めたと認識される閾値:デフォルトでは3ピクセルドラッグするか、1秒間つかんでいる)を超えたタイミング
onDrag Drag中のマウスが動かされたときの全てで発生する
onDragEnter Dragされたオブジェクトが、初めてターゲットとなりえるDDオブジェクトと交差したたタイミング
onDragOver DDオブジェクト上でマウスが動いた全てのタイミング
onDragOut onDragEnterが発生したオブジェクト上から離れたタイミング
onDragDrop ドラッグされたオブジェクトがドロップされたタイミング
onInvalidDrop ドラッグされたオブジェクトが、Dropされるターゲットの無い場所にDropされたタイミング
endDrag startDragされた後、マウスが放されたタイミング
onMouseUp マウスが放されたタイミング(ドラッグがスタートしてるか否かに関係ない)

また、このイベントに対応して、DDオブジェクトのインスタンスに対して、onメソッドで追加できるイベント(カスタムイベント)が紹介されている。

イベント 意味
mouseDownEvent マウスが押されたタイミング(必ずしもDragを始めるタイミングではない)
mouseUpEvent ドラッグが終わったときにDDMgr内で発生する
startDragEvent マウスが押されて、Drag threshold(ドラッグを始めたと認識される閾値:デフォルトでは3ピクセルドラッグするか、1秒間つかんでいる)を超えたタイミング
endDragEvent startDragされた後、マウスが放されたタイミング
dragEvent Drag中のマウスが動かされたときの全てで発生する
invalidDropEvent ドラッグされたオブジェクトが、Dropされるターゲットの無い場所にDropされたタイミング
dragOutEvent onDragEnterが発生したオブジェクト上から離れたタイミング
dragEnterEvent Dragされたオブジェクトが、初めてターゲットとなりえるDDオブジェクトと交差したたタイミング
dragOverEvent DDオブジェクト上でマウスが動いた全てのタイミング
dragDropEvent ドラッグされたオブジェクトがドロップされたタイミング

これらの使い方として

var dd = new YAHOO.util.DD('demo');
    dd.on('dragEvent', function(ev) {
        YAHOO.log('Element is being dragged.');
    }, dd, true);

が紹介されている。詳細については、YAHOO.util.DDのAPIドキュメントを参照。

パフォーマンスへの影響として、onDrag、onDragOverのようなカーソル位置を常に捕捉するようなイベントは高コストらしい。たしかにその通りだ。

次にも、Point Mode versus Intersect Modeとして重要な事項が記載されている。
要するに、InteractをPoint(カーソルポイント)で認識するか、ドラッグするインスタンスとドロップされるインスタンスの(図形的な)交差で認識するかの説明なのだが、デフォルトでは、Pointとなっているとのこと。
これは、DDオブジェクトのプロパティー値として設定するもので、

//set Drag and Drop to Intersect mode:
YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;

//set Drag and Drop to Point mode (default):
YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;

として変更することができる、と書いてある。