japan.internet.comThe Internet & IT Network
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2008年9月5日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
デベロッパー2006年2月21日 10:10

XMLとXSLを使った高度なUIデザイン:パート4

海外海外internet.com発の記事
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • Buzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!

はじめに

 この連載では、XMLとXSLを使った高度なUIデザインに挑戦します。1回に1つずつ、XMLとXSL(XML用のスタイルシート言語)を使用して高度なユーザーインタフェース(UI)コンポーネントを作成していきます。

 今回は、第1回に作成したフォルダツリーを発展させ、フォルダツリー内のエンティティをドラッグして別のツリー内にドロップする方法を紹介します。

ドラッグ&ドロップコントロール

 今回のドラッグ&ドロップコントロール(DragControl)はクライアント側に存在し、次のように定義されます。

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

 entityプロパティには、ある場所から別の場所へと移動するオブジェクトへの参照が格納されます。移動は、同じツリー内での移動、または別のツリーへの移動のどちらでも構いません。このプロパティはbeginDrag()メソッド内で設定されます。

target

 targetプロパティには、現在のドラッグ&ドロップ操作のドロップ先への参照が格納されます。ユーザーがマウスポインタを別のエンティティに動かすと、値が変更されます。このプロパティはsetTarget()メソッド内で設定されます。

origin

 originプロパティには、オブジェクトのドラッグ元フォルダへの参照が格納されます。ユーザーがドラッグ先を指定せずにマウスの左ボタンを放した場合は、このフォルダの場所にエンティティが戻されます。originプロパティは、beginDrag()メソッドによって設定されます。

enabled

 ドラッグ&ドロップ操作を実際に開始するのはenabledプロパティです。ユーザーがエンティティを選択した状態でマウスを一定ピクセル数だけドラッグすると、このプロパティがtrueに設定されます。今回のコードでは、開始とみなされるのに必要なドラッグ範囲が5ピクセルになっています。このプロパティの変更はmove()メソッド内で行います。

beginX

 このプロパティには、ドラッグ&ドロップルーチン開始時点のマウスポインタのX座標が入ります。beginXプロパティはbeginDrag()メソッド内で設定されます。

beginY

 このプロパティには、ドラッグ&ドロップルーチン開始時点のマウスポインタのY座標が入ります。beginYプロパティはbeginDrag()メソッド内で設定されます。

メソッド

beginDrag()

 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)スタイルシート内でエンティティに関連付けられています。

図1 beginDrag()メソッドの配置
図1 beginDrag()メソッドの配置

 このメソッドでは、まず、(コンテキストメニュー用に使われる)マウスの右ボタンではなく、左ボタンによってイベントが発生したことを確認します。次に、適切なプロパティ値を設定し、クライアントブラウザ内でのイベント伝播をキャンセルします。

endDrag()

 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スタイルシート内でエンティティに関連付けられています。

図2 endDrag()メソッドの配置
図2 endDrag()メソッドの配置

setTarget()

 setTarget()メソッドの定義は次のとおりです。

function setTarget(obj) {
  if(this.entity != null && this.entity != obj) {
      this.target = obj;
  }
  window.event.cancelBubble = true;
}

 このメソッドは、まず現在のエンティティが存在すること、およびこの選択中のエンティティが移動先のエンティティでないことを確認します。次に、DragControltargetプロパティを設定します。その後、DragControlはクライアントブラウザ内でのイベント伝播をキャンセルします。

 このメソッドは、XSLTスタイルシート内でエンティティに関連付けられています。

図3 setTarget()メソッドの配置
図3 setTarget()メソッドの配置

setPosition()

 setPosition()メソッドの定義は次のとおりです。

function setPosition() {
  this.entity.style.left = window.event.x;
  this.entity.style.top = window.event.y - 10;
}

 このメソッドは、選択されているエンティティのXおよびY座標を、単純に現在のマウスイベントのXおよびY座標に書き換えます。このメソッドはmove()メソッド内から呼び出されます。

 このメソッドは、サンプルの「tree.js」ファイル内でエンティティに関連付けられています。

図4 setPosition()メソッドの配置
図4 setPosition()メソッドの配置

move()

 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ピクセル以上ドラッグしていることを確認します。次に、このエンティティを現在のツリーから取り出してドキュメント本体に移動させます。エンティティが常にマウスカーソルの隣に表示されるようにするために、このメソッドをドキュメントオブジェクトのonmousemoveイベントを介して継続的に呼び出す必要があります。

 このメソッドは、サンプルの「tree.js」ファイル内でエンティティに関連付けられています。

図5 move()メソッドの配置
図5 move()メソッドの配置

reset()

 reset()メソッドの定義は次のとおりです。

function reset() {
  document.onmouseup = null;
  document.onmousemove = null;

  this.entity = null;
  this.origin = null;
  this.target = null;
}

 このメソッドは、ドキュメントおよびDragControlオブジェクトのクリーンアップだけを行います。ドラッグ&ドロップが完了またはキャンセルされると、必ずこのメソッドが呼び出されます。

 このメソッドは、XSLTスタイルシート内でエンティティに関連付けられています。

図6 reset()メソッドの配置
図6 reset()メソッドの配置

 それでは、フォルダツリーのドラッグ&ドロップコントロールのライブデモを見てみましょう。このデモには2つのツリーがあり、その下に、順序を示す「One」から「Six」までのタイトルを持つエンティティが用意されています。「One」の下に「Two」、「Two」の下に「Three」というようにそれぞれがネストされるようにドラッグしてみてください。図7に示すように、「One」というエンティティをTree1からTree2にドラッグすると、先ほど番号順に並べた(ネストさせた)「One」以下のすべてのエンティティもそれにならってTree1からTree2に移動します。

図7 ツリーからツリーへのドラッグ&ドロップ
図7 ツリーからツリーへのドラッグ&ドロップ

終わりに

 本稿の内容が、Webアプリケーションインタフェースの質的向上に役立てば幸いです。質問・コメント・提案があれば、筆者紹介にあるアドレスまで遠慮なくメールをお送りください。

本連載のその他の記事

著者紹介

Joe Slovinski(Joe Slovinski)
1993年以来、Webアプリケーションの開発に継続的に携わる。本稿で紹介したコードについてのお問い合わせはJoe Slovinskiまで。
関連テーマ
最新トップニュース
データメーション
【データメーション】
OSについて気に入らないこと(9月5日)
ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」
【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
「導入期〜成長期へ!一歩一歩と前進を目指す『Annoii(アノイ)』」/maka hou,Inc.(9月5日)
最新テクノロジーの意外な処方箋
【最新テクノロジーの意外な処方箋】
グリッドコンピューティング技術でETに遭遇(9月5日)
Graphic Design Forum
【Graphic Design Forum】
古い Emigre を探して (9月3日)
エンジニアの独り言
【エンジニアの独り言】
データをローカルに保存するWebアプリケーション(8月22日)
デスマーチからの脱却
【デスマーチからの脱却】
30min. iPhoneアプリリリース(8月18日)
最新ハイテク講座
最新ハイテク講座
なぜ勝った? 世界No.1シェアをつかんだ“Windows”(9月5日)
developer.com
developer.com
デザインパターンの使い方: Composite(9月5日)
最新アフィリエイト事例にみる成功の法則
最新アフィリエイト事例にみる成功の法則
コンバージョンレートを高めよう!(9月5日)
百式のネットビジネス研究
百式のネットビジネス研究
ガジェット購入時に将来の買取保証プランを提供する「TechForward」(9月5日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(9月4日)
「IT の耳」
「IT の耳」
【書評】『検索にガンガンヒットさせる SEO の教科書』――SEO テクニックで効果的に PR する(9月4日)
検索エンジンマーケティング
検索エンジンマーケティング
果たしてモバイル SEO は必要なのか?(9月4日)
Eメールマーケティング事情
Eメールマーケティング事情
読者が迷惑メールと認識する時…(9月3日)
日本と韓国のインターネットビジネス最新動向調査
日本と韓国のインターネットビジネス最新動向調査
日本と韓国の動画サイト比較1―現状(9月3日)
SNSをビジネスに活用しよう
SNSをビジネスに活用しよう
「しまじろう」に学ぶ企業内コミュニティの活性化のポイント(9月2日)
海外のインターネットコムアメリカ韓国ドイツトルコ
Copyright 2008 Jupitermedia Corporation All Rights Reserved.http://www.internet.com/