XMLとXSLを使った高度なUIデザイン:パート4はじめにこの連載では、XMLとXSLを使った高度なUIデザインに挑戦します。1回に1つずつ、XMLとXSL(XML用のスタイルシート言語)を使用して高度なユーザーインタフェース(UI)コンポーネントを作成していきます。 今回は、第1回に作成したフォルダツリーを発展させ、フォルダツリー内のエンティティをドラッグして別のツリー内にドロップする方法を紹介します。 ドラッグ&ドロップコントロール 今回のドラッグ&ドロップコントロール( function DragControl() { this.entity = null; this.target = null; this.origin = null; this.enabled = false; this.beginX = null; this.beginY = null; this.beginDrag = beginDrag; this.endDrag = endDrag; this.setTarget = setTarget; this.setPosition = setPosition; this.move = move; this.reset = reset; } このコントロールには、次のメンバが含まれます。 プロパティentity target origin enabled ドラッグ&ドロップ操作を実際に開始するのは beginX このプロパティには、ドラッグ&ドロップルーチン開始時点のマウスポインタのX座標が入ります。 beginY このプロパティには、ドラッグ&ドロップルーチン開始時点のマウスポインタのY座標が入ります。 メソッドbeginDrag() function beginDrag(obj) { if(window.event.button == 1) { document.onmousemove = function anonymous() { dragControl.move(obj) }; this.origin = obj.parentNode; this.entity = obj; this.beginX = window.event.x; this.beginY = window.event.y; window.event.cancelBubble = true; } } このメソッドは、XSL変換(XSLT)スタイルシート内でエンティティに関連付けられています。 このメソッドでは、まず、(コンテキストメニュー用に使われる)マウスの右ボタンではなく、左ボタンによってイベントが発生したことを確認します。次に、適切なプロパティ値を設定し、クライアントブラウザ内でのイベント伝播をキャンセルします。 endDrag() function endDrag() { if(this.entity != null) { this.entity.style.position = "static"; this.entity.style.left = null; this.entity.style.top = null; this.entity = this.entity.removeNode(true); if(this.target != null) { dragControl.target.appendChild(this.entity); if(this.target.open != "true") { clickOnEntity(this.target); } } else { this.origin.appendChild(this.entity); } document.onmousemove = null; document.onmouseup = null; this.entity = null; this.target = null; this.enabled = false; } } このメソッドは、まずエンティティが選択されていることを確認します。次に、ユーザーが現在ドラッグ先を選択しているかどうかに応じて、エンティティを元の場所に戻すか(ドラッグ先が選択されていない場合)、新しい場所に移動させるか(ドラッグ先が選択されている場合)のいずれかを行います。 このメソッドは、XSLTスタイルシート内でエンティティに関連付けられています。 setTarget() function setTarget(obj) { if(this.entity != null && this.entity != obj) { this.target = obj; } window.event.cancelBubble = true; } このメソッドは、まず現在のエンティティが存在すること、およびこの選択中のエンティティが移動先のエンティティでないことを確認します。次に、 このメソッドは、XSLTスタイルシート内でエンティティに関連付けられています。 setPosition() function setPosition() { this.entity.style.left = window.event.x; this.entity.style.top = window.event.y - 10; } このメソッドは、選択されているエンティティのXおよびY座標を、単純に現在のマウスイベントのXおよびY座標に書き換えます。このメソッドは このメソッドは、サンプルの「tree.js」ファイル内でエンティティに関連付けられています。 move() function move(obj) { if(window.event.x < this.beginX - 5 || window.event.x > this.beginX + 5 || window.event.y < this.beginY -5 || window.event.y > this.beginY + 5 && this.enabled == false) { obj.style.position = "absolute"; obj.style.filter = "alpha(opacity=’60’)"; this.setPosition(); this.enabled = true; obj = obj.removeNode(true); document.body.appendChild(obj); document.onmouseup = function anonymous() { dragControl.endDrag() }; } else if(this.enabled == true) { this.setPosition(); } } このメソッドは、まず、ユーザーが実際にエンティティを(X軸/Y軸、正/負を問わず)いずれかの方向に少なくとも5ピクセル以上ドラッグしていることを確認します。次に、このエンティティを現在のツリーから取り出してドキュメント本体に移動させます。エンティティが常にマウスカーソルの隣に表示されるようにするために、このメソッドをドキュメントオブジェクトの このメソッドは、サンプルの「tree.js」ファイル内でエンティティに関連付けられています。 reset() function reset() { document.onmouseup = null; document.onmousemove = null; this.entity = null; this.origin = null; this.target = null; } このメソッドは、ドキュメントおよび このメソッドは、XSLTスタイルシート内でエンティティに関連付けられています。 それでは、フォルダツリーのドラッグ&ドロップコントロールのライブデモを見てみましょう。このデモには2つのツリーがあり、その下に、順序を示す「One」から「Six」までのタイトルを持つエンティティが用意されています。「One」の下に「Two」、「Two」の下に「Three」というようにそれぞれがネストされるようにドラッグしてみてください。図7に示すように、「One」というエンティティをTree1からTree2にドラッグすると、先ほど番号順に並べた(ネストさせた)「One」以下のすべてのエンティティもそれにならってTree1からTree2に移動します。 終わりに本稿の内容が、Webアプリケーションインタフェースの質的向上に役立てば幸いです。質問・コメント・提案があれば、筆者紹介にあるアドレスまで遠慮なくメールをお送りください。 本連載のその他の記事著者紹介Joe Slovinski(Joe Slovinski)
1993年以来、Webアプリケーションの開発に継続的に携わる。本稿で紹介したコードについてのお問い合わせはJoe Slovinskiまで。
関連記事 関連テーマ 最新トップニュース
|
なぜ勝った? 世界No.1シェアをつかんだ“Windows”(9月5日 11:00)
ソフトバンクモバイル、8月の純増数は約16万件――携帯電話契約数に関する速報(9月5日 14:40)
【今週の Web ミミズク】Google と Apple でにぎわうニュースサイト(9月5日 16:50)
TCA、8月度の携帯契約数を発表――ソフトバンクが16か月連続純増 No.1 に(9月5日 18:00)
読者が迷惑メールと認識する時…(9月3日 10:00)
私の周りは“geek out”している人ばかり(9月5日)
|