2012年2月26日日曜日

[JavaScript]イベントの委譲(delegation)

JavaScriptでは、イベントのバブリングを利用し、親要素にイベント処理を委譲することができます。
イベント委譲の利点は、イベントを発生させる要素ごとにイベントを設定しなくて済み、コードの見通しがよくなることです。

sample


サンプルとして、[start], [stop], [reset] ボタン3つで操作する、10分の1秒単位で計測するストップウォッチを作成しました。

ポイントとしては、
  • 各ボタンの親要素である、id="controller" のdiv要素にのみ、onclick イベントリスナを設定している。(22行目)
  • div要素内でonclickイベントが発生したら、発生元のid属性をチェックし、各ボタンごとの処理を呼び出している。(30行目)

ことです。

サンプルコード

jQueryでイベント委譲する場合


jQuery では、.delegate() メソッドが用意されているので、より簡単にイベント委譲を実装できます。

$("div#controller").delegate("input#start", "click", handler);

まとめ

  • 同一要素内でたくさんのイベントリスナをセットする場合は、イベント委譲でまとめられないか検討する!



参考文献
JavaScript パターン p196 - p197
JavaScriptパターン ―優れたアプリケーションのための作法
JavaScriptパターン ―優れたアプリケーションのための作法

2012年2月14日火曜日

[jQuery] jQueryオブジェクト から DOM オブジェクトに変換する

あまり使いどころはなさそうだけど・・

get() で返されるのはDOM オブジェクト


jQueryオブジェクトの集合に対して、.get()メソッド(Ajax のgetとは異なる)を実行すると、
jQuery オブジェクトではなく、DOM オブジェクトの配列が返されます。

また、get() にインデックスを渡すか、jQueryオブジェクトの集合に[] でアクセスすれば、インデックスで指定した要素のみDOM オブジェクトとして取得することも可能です。

jQueryのアプリケーションで DOM オブジェクトのメソッドやプロパティtが使いたかったら、.get()でDOMオブジェクトに変換すればOK!

動作確認サンプル (Chrome 17 で確認しました。)


まとめ

  • .get() で返されるのは、DOM オブジェクト!!

参考文献
jQuery クックブック p59 - p62
jQueryクックブック
jQueryクックブック

2012年2月11日土曜日

[jQuery] jQuery.animation() でスクロールをアニメーション処理

ページ内リンクへの移動をアニメーションで実行したいと思い立ってjQueryのマニュアルを確認したところ、
特別なプラグインを導入しなくても、jQuery.animate() メソッドで実現できることがわかったのでまとめました。

.animate() に渡せるプロパティー


.animate() メソッドでは、アニメーションの動きを、cssプロパティと値を定義したオブジェクトを渡して指定します。
基本的に、数値を指定できるcssプロパティ(width, height, opacity など)のみ指定できますが、
cssのプロパティ以外でも、scrollTop ,scrollLeft など、アニメーション可能なプロパティが定義されています。

今回は下方向に画面をスクロールさせたいので、アニメーションさせるプロパティに"scrollTop"を指定します。

scrollTop で下方向にスクロール


というわけで、class に"scrollAnchor" が指定されたアンカーをクリックすると、
リンク先の要素までウィンドウをスクロールするプログラムを作成してみました。
(ちなみに、JavaScriptが無効になっていても移動は可能です)

ポイントとしては、
  • .offset()メソッドで、リンク先の要素のドキュメント内の縦方向の相対位置を取得している
  • animationメソッドはbody要素に対して実行している
  • ことです。

サンプル(jQuery-1.7.1 で実行。動作は chrome 16 , IE6で確認しました。)

<!-- 以上省略 -->
<body>
 <a href="#scrollDest" class="scrollAnchor">scroll!</a>

 <div id="container">
     <div style="height: 500"></div>
     <div style="height: 500"></div>
     <div style="height: 1000; width: 500; background-color: black" id="scrollDest"></div>
 </div>

 <script type="text/javascript" src="./lib/jquery-1.7.1.js"></script>
 <script type="text/javascript">

     var body = $("body:first");
     $("a.scrollAnchor").click(function(evt){
         // デフォルトのanchorの処理を停止
         evt.preventDefault();           

         var destId = $(this).attr("href");

         // .offset()で、リンク先要素のドキュメント内の相対位置を取得
         var destTop = $(destId).offset().top;   

         // ウィンドウをスクロールさせるために、body要素に対してanimateメソッドを呼び出す
         body.animate({scrollTop: destTop}, 1000);
     });

 </script>
</body>
<!-- 以下省略 -->


要素内でのスクロール


overflow: scroll もしくは overflow: hidden が設定されている要素内で、特定の子要素までスクロールさせたい場合のサンプルです。
このケースでは、.position() メソッドで要素内の位置を取得しています。

サンプル

<!-- 以上省略 -->
<body>
 <div id="container" style="height: 1000; overflow: scroll">
     <a href="#scrollDest" class="scrollAnchor">scroll!</a>
     <div style="height: 500"></div>
     <div style="height: 500"></div>
     <div style="height: 1000; width: 500; background-color: black" id="scrollDest"></div>
 </div>

 <script type="text/javascript" src="./lib/jquery-1.7.1.js"></script>
 <script type="text/javascript">
     var container = $("div#container");

     $("a.scrollAnchor").click(function(evt){
         evt.preventDefault();

         var destId = $(this).attr("href");
         var destTop = $(destId).position().top;   // .position()で要素内の相対位置を取得

         container.animate({scrollTop: destTop}, 1000);
     });

 </script>
</body>
<!-- 以下省略 -->


まとめ


  • ページ内要素への移動をアニメーション化する場合は、jQuery.animate() メソッドに、"scrollTop" プロパティを持つオブジェクトを渡す
  • ウィンドウをスクロールさせるのか、特定の要素内でスクロールさせるのかに注意する

参照URL
.animate() - jQuery API:
http://api.jquery.com/animate/

参照書籍
jQuery クックブック
jQueryクックブック
jQueryクックブック

2012年2月8日水曜日

[JavaScript] parseInt() と Number.toString() で 数値 <=> 文字列 変換

文字列を数値に変換 parseInt(string, radix)


数値を表す文字列を10進数の整数の値に変換するには、組み込みのparseInt() 関数を使います。
ユーザーからの入力や、jsonで受け取ったのデータを数値として扱う場合などは、必ずparseInt() で数値に変換してから、処理を行います。

sample (以下すべて chrome 16 で実行しました。)
console.log(parseInt("10px", 10));   //10 stringは、数値と解釈できる文字で始まっていれば、後の変換できない文字は無視される

console.log(parseInt("1111", 2));    //15
console.log(parseInt("0xFFFF", 16)); //65535

console.log(parseInt("hoge", 10));   //NaN 数値変換不能な文字列が与えられた場合は、NaN が返る


注意点としては、省略可能な第2引数の radix で、文字列が表している数値の基数を必ず指定することです。

もし radix を指定しないと、自動的に基数が判定されてしまうので、
たとえば、"010" など,"0" で始まる文字列を,頭の0を除いて10進数として扱いたい場合に、"010" は8進数の数値を表現している文字列と解釈され、8 が返されます。

sample
var str = "010"

//radix を省略した場合
console.log(parseInt(str));  //8 <= "010" が8進数をあらわす数値として解釈された

//"010" を10進数の数値として解釈
console.log(parseInt(str, 10)); //10

数値を文字列に変換する Number.toString(radix)


反対に、10進数で表された数値を、任意の基数で表された数値の文字列に変換する場合は、 NumberオブジェクトのtoString()メソッドを使います。
console.log( (15).toString(2) );     // "1111"
console.log( (65535).toString(16) ); // "ffff"

まとめ


  • 文字列を数値に変換するには、組み込み関数の parseInt(string, radix) を使う
  • parseInt の第2引数には、必ず、文字列があらわしている数値の radix を渡す!
  • parseIntの逆で、数値を文字列に変換したい場合はNumber.toString()

参照URL
Ecma-262.pdf 15.1.2.2 parseInt(string, radix)
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

toString - MDN
https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/Number/toString