Secrets of the JavaScript Ninja 10章を読んで来た

開催からずいぶん時間が経ってしまった(7/2にやりました^^;)のですが、10章(Strategies for Cross-Browser Code)を読みました!

前回の計画の通り、7,8,9章はライブラリ作者向けの内容ということで後回しにしました。


この章はほとんどコードが出てこないので、予習がしんどかったです。。。


予習はしんどかったですが、こういうことに気をつけるんだな、ということが分かったので良かったです。
以下、まとめです。

  • サポートすべきブラウザ
    • 最新のバージョン(Current)、1つ前(Previous)、1つ後(Next)が一般的だそうです.
    • 例外としてIEは6.0もサポートの必要あり...
  • 開発時に注意すること
    • どこまでの範囲、サポート対象とするかのバランスが大事.
  • ブラウザのバグ
    • 他の機能と同等になるようにシミュレーションしてしまう.
  • 外部コードとマークアップ
    • Prototypeの変更やHTML要素をjsでコントロールするときに注意すること
      • ObjectオブジェクトのPrototypeにプロパティを生やすと、for inループを使ったときにhasOwnPropertyしなきゃいけなくなる
      • formタグのidに"form"と名付けたり、submitボタンのidに"submit"と名付けたりすること.
        • さすがにこれはやらないと思いますが...
  • とても古いブラウザへの対応
    • IE4とか、とても古いブラウザの場合、cssやjsは使わずに、HTMLだけのページを表示してあげる対応方法
  • ブラウザのバグ!?
    • ブラウザのバグなんだけど、バグったままの挙動で、今までエンドユーザが実装してきてしまったので、修正すると、既存のコードが動かなくなるため直せない.

例として、adoptNodeというメソッドの話が載っていました.

  • Regressions(回帰!?と訳せば良いのでしょうか...)
    • IEだけイベントの扱い方が異なる.
      • IEはattachEvent, 他のブラウザはaddEventListener
      • この2つのメソッドをブラウザを気にせず使えるようなAPIの例として
function attachEvent( elem, type, handle ) {
  // bind event using proper DOM means
  if ( elem.addEventListener )
    elem.addEventListener(type, handle, false);
  // use the Internet Explorer API
  else if ( elem.attachEvent )
    elem.attachEvent("on" + type, handle);
}

が載っていました.

  • APIの変更がないかどうか、主要ブラウザ(IE, Firefox, WebKit, Opera)の動向を1, 2週間毎に確認すると良いとのこと.
  • 安全なクロスブラウザ対策
    • IECSSのwidth, heightプロパティに負の値を設定できてしまうため、どのブラウザでもそのようなことが出来ないようにする
if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
    • またまたIEですが、input要素の属性を変更できないようにする
if ( name == "type" && elem.nodeName.toLowerCase() == "input" &&
elem.parentNode )
  throw "type attribute can't be changed";

なお、この例は実際にjQueryのコード内で使われています.

  • Object Detection
    • ブラウザ間で別のAPIが用意されているものを共通のやり方で使えるようにする
      • また、さっきのイベント周りを扱う関数が紹介されていました.
    • また、addEventListener, attachEventメソッド自体がないブラウザ(どんだけ古いんだ...)向けに、
if ( typeof document !== "undefined" &&
     (document.addEventListener || document.attachEvent) &&
     document.getElementsByTagName && document.getElementById ) {
     // We have enough of an API to work with to build our application
} else {
  // Provide Fallback
}

というコードも紹介されていました.Fallback部分には,

  • 機能を減らして、そのブラウザで使えるjsの機能だけ使う
  • jsなしのページへリダイレクト
  • 簡素なバージョンのサイトへリダイレクト(Gmailのような簡易HTMLページ)

のような処理を書くとよいそうです.

  • 機能をシミュレートする
    • あるブラウザでは実装されていない機能を実装してしまう方法です.
  • テストできない、難しい場合
    • イベントハンドラがどの要素にバインドされているかどうかはテストできない.
    • イベントが発火するかどうかを判断すること
    • ブラウザがクラッシュする
    • APIのパフォーマンス
      • ブラウザによって早かったり遅かったりする.
    • Ajaxリクエストが動いているかどうかを判断すること
    • テストできない機能は厄介ですが,ほとんどの場合、Object DetectionやFeature Simulateを使う事で回避することができますとのこと.
  • 実装時の注意点
    • 特定のブラウザの機能にはバグが潜んでいると疑ってかかる.その機能をテストすることが効果的.
    • ブラウザの切り分けには,userAgentが最も使われるが,userAgentだけでは十分でないことがあるので注意
      • operaIEになっていたり、IEGeckoになっていたり...
    • ある問題を扱うとき,全てを取り除く事は難しい場合がある.そんなときは開発者が妥協点を提案することも大事.
  • まとめ
    • クロスブラウザ開発の3つのポイント
      • コードサイズを小さく保つ
      • パフォーマンスのオーバーヘッドを最小限に抑える事
      • 提供されているAPIが各ブラウザで同じように動くようにする事

次は12章( DOM Modification )です!