SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

JavaScriptとjQueryでデスクトップアプリに負けない操作性のWebアプリケーションを作る

ドラッグアンドドロップ、マウス選択、パン、ズームなどができるWebアプリケーション

設定

 コードを簡潔に保つために、まずはリスト1のソースコードから始めます。これは完全なアプリケーションのモックアップとして機能するもので、4つのDIVを含む単純なWebページです。4つのDIVは、ユーザーが操作する視覚アイテムを表します。このページがどのように表示されるかを図1に示します。

図1 モックアップWebページ: 4つのDIVはユーザーが操作する視覚アイテムを表す。
図1 モックアップWebページ: 4つのDIVはユーザーが操作する視覚アイテムを表す。
リスト1 モックアップWebページのHTMLコード
<html>
<head>
  <script src="lib/jquery-1.2.6.js"></script>
  <script src="lib/jquery-ui-core-drag-drop-select-1.5.3.js"></script>
  <script src="lib/jquery.mousewheel.js"></script>
  <link rel="stylesheet" 
        href="css/demo.css"
        type="text/css">
  <title>Mockup</title>
  <script>
    $(document).ready(function() {
      // our JavaScript code will go here
    });
  </script>
</head>
<body>
  <h1>Mockup</h1>
  <p>
    This is the mockup application 
    that we are going to enrich.
  </p>
  <div id="container">
    <div id="box1" class="box">Blue</div>
    <div id="box2" class="box">Red</div>
    <div id="box3" class="box">Yellow</div>
    <div id="box4" class="box">Green</div>
  </div>
</body>
</html>

要素のドラッグと移動

 要素のドラッグと移動は、デスクトップパラダイムにより近づくために最初に追加しなければならない機能です。jQuery UIのおかげで、これを行うのはとても簡単です。次のコードをモックアップページのheadセクションに追加するだけでよいのです。

<html>
<head>
  <!-- ... omissis -->
  <script>
    $(document).ready(function() {
      $('.box').draggable({
        opacity: 0.5,
        cursor: 'move',
        zIndex: 10000
      });
    });
  </script>
  <style type="text/css" media="screen">
    .box {
      cursor: move;
    }
  </style>
</head>
<!-- ... omissis -->
</html>

 このコードでは、box CSSクラスを持つすべての要素に対してdraggable()ミューテータメソッドを使用しています。このメソッドは、当該のDOM要素がマウスのクリックとドラッグを感知するようにします。

 ドラッグ操作は一連のオプションでカスタマイズすることができます。この例では、ドラッグの最中にアイテムを半透明にすること、操作の目的を分かりやすく示す特別なカーソルを表示すること、そしてドラッグされるアイテムを他のものより手前に表示すること(z-indexの値を大きくすることで実現)を宣言しています。これでアイテムをページの中であちこちに移動させることができます(図2を参照)。

図2 アイテムがページ上でドラッグ可能に:ドラッグするアイテムを他のものより手前に表示するよう宣言できる。
図2 アイテムがページ上でドラッグ可能に:ドラッグするアイテムを他のものより手前に表示するよう宣言できる。

 公式ドキュメントに記述されているように、ドラッグ中のさまざまな段階で通知を受けるリスナをアタッチすることもできます。これを利用してグループドラッグ(1つの要素をドラッグすると複数の要素が同時に移動する)を実現することができます。この機能は選択管理とともに後で使用します。それにより、ユーザーがデスクトップアプリケーションの場合と同じように、ページ上のアイテムを選択して移動できるようになります。

 グループドラッグを実装するには、3つのリスナを追加する必要があります。この3つはそれぞれマウスドラッグの始まり、最中、終わりに対応するものです。これらのリスナは移動するすべての要素の相対位置を記録し、カーソルの下にある要素がドラッグされている間は、関連する要素の位置を継続的に更新します。このコードは少し長くなるので、リスト2に示してあります。サンプルコードには完全な例が含まれています。

リスト2 グループドラッグを実装するためのコード
<html>
<head>
  <!-- ... omissis -->
  <script>
    $(document).ready(function() {
      
      // define which elements will move 
      // concurrently with a dragged one.
      var dragGroups = {
        // dragged item : affected items
        'box1' : [ 'box2' ],
        'box2' : [],
        'box3' : [ 'box1', 'box4'],
        'box4' : []
      };
      
      $('.box').draggable({
        opacity: 0.5,
        cursor: 'move',
        zIndex: 10000,
        
        // figure out all the initial positions 
        // for the affected elements, relative to 
        // the one being dragged, and store them.
        // We use the data() function to store 
        // temporary information on the objects themselves.
        start: function(ev, ui) {
          ids = dragGroups[ui.helper[0].id];
          for (var i = 0; i < ids.length; i++) {
            $('#' + ids[i]).data(
                "top0", 
                parseInt($('#' + ids[i]).css("top"),10) - 
                  parseInt($(ui.helper[0]).css("top"),10));
            $('#' + ids[i]).data(
              "left0", 
              parseInt($('#' + ids[i]).css("left"),10) - 
                parseInt($(ui.helper[0]).css("left"),10));                
          }          
        },
        
        // whenever the dragged item moves, update 
        // the positions of all the affected items, 
        // updating their position with the same relative offset.
        drag: function(ev, ui) {
          ids = dragGroups[ui.helper[0].id];          
          for (var i = 0; i < ids.length; i++) {
            if (ids[i] != ui.helper[0].id) {
              $('#' + ids[i]).css(
                'top',
                $('#'+ids[i]).data("top0") + ui.position.top);
              $('#' + ids[i]).css(
                'left', 
                $('#'+ids[i]).data("left0") + ui.position.left);              
            }
          }
        },
        
        // cleanup temporary data at the end
        stop: function(ev, ui) {
          ids = dragGroups[ui.helper[0].id];          
          for (var i = 0; i < ids.length; i++) {          
             $('#'+ids[i]).removeData("top0");
             $('#'+ids[i]).removeData("left0");
          }        
        }        
      });
    });
  </script>
  <style type="text/css" media="screen">
    .box {
      cursor: move;
    }
  </style>  
</head>
<body>
  <!-- ... omissis -->
</body>
</html>

次のページ
選択の処理

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Riccardo Govoni(Riccardo Govoni)

2003年からJ2EE開発者としてイタリアの金融サービス会社に勤務。ソフトウェアアーキテクトとして従来の銀行システムのWebフロントエンドの設計に従事。物理学修士。SCJP(Sun Certified Java Programmer)資格を持つ。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3559 2009/03/06 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー