メッセージ欄

2010年9月の日記

一覧で表示する

Chapter 17. JavaScript Libraries
2010/09/14(火) 25:48 Javascriptはてブ情報 はてブに登録 はてブ数

JavaScriptライブラリについて。

17.1 Packaging Your Code

Chapter 16. JavaScript Objects - prog*sigの話で出てきたけど、オブジェクトリテラルによってまとめて再利用のためにまとめてみる。
グローバル名前空間の占有率を減らすことは、他のライブラリとの衝突を避ける事にも繋がる。
function getElem(identifier) {
   return document.getElementById(identifier);
}
function stripslashes (str) {
      return str.replace(/\\/g, '');
}
function removeAngleBrackets(str) {
      return str.replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
// グローバル名前空間を3つも使ってる。
// =>オブジェクトにまとめる。
var jscbObject = {
   // return element
   getElem : function (identifier) {
      return document.getElementById(identifier);
   },
   stripslashes : function(str) {
      return str.replace(/\\/g, '');
   },
   removeAngleBrackets: function(str) {
      return str.replace(/</g,'&lt;').replace(/>/g,'&gt;');
   }
};
何度も使うようなコードは関数(メソッド)にして、モジュール化(Modularize)することで再利用性が高まります。またコードもすっきりする。

17.2 Testing Your Code with JsUnit

JsUnitの使い方について。

17.3 Minify Your Library

配布するときにコードをコンパクトにするために圧縮。
http://javascriptcompressor.com/ を紹介しただけー

17.4 Hosting Your Library

オープンソースでありたいけど、自分のサーバで配布とかはしたくないとき。
  • Google Code
SVNかMercurialが使える。
Wiki, Downloads, Issues, Sourceのダウンロードと一通りそろっている。
  • Source Forge
過去、場所によってアクセス制限があるのでオープンではないかもしれない。
  • github
Google codeと違ってprivateは有料ではあるけど、JSの場合は関係ない。

17.5  Using an External Library: Building on the jQuery Framework

jQueryなどの著名なライブラリは多くの人によって使われ試されているので、
独自のライブラリを使うより安全にできる。

17.6 Using Existing jQuery Plug-ins

jQueryにはいろんなプラグインがあるが、衝突してないかを調べる。
なるべく汎用的すぎるものは避ける、ここの目的に沿ったものを。
Unit testをしてみる。
動作がおかしいと思ったとき
  • バグやissueが無いか検索
  • アップデートがないかを調べる
  • jQueryの新しめのやつ自体がバグってる場合も

17.7  Convert Your Library to a jQuery Plug-in

オリジナルのライブラリをjQueryプラグインにするには。
もし、jQueryでメソッドチェーン的に呼び出せるようにしたいなら、 jQuery.fnにメソッドを付ける
jQuery.fn.increaseWidth = function() {
   return this.each(function() {
      var width = $(this).width() + 10;
      $(this).width(width);
   });
};
// $("#test").increaseWidth() // =>可能
特にjQueryのメソッドチェーンで呼び出せる必要がないならjQueryオブジェクトを拡張する。
jQuery.bbHelloWorld = function(who) {
   alert ("Hello " + who + "!");
};
// $("#test").bbHelloWorld() //=> 無理
// $.bbHelloWorld(); // =>可能
毎回jQueryって書いて拡張するのが面倒なら
jQuery.fn.flashBlueRed = function() {
    return this.each(function() {
      var hex = rgb2hex($(this).css("background-color"));
      if (hex == "#0000ff") {
        $(this).css("background-color", "#ff0000");
      } else {
        $(this).css("background-color", "#0000ff");
      }
    });
 };
// => 下みたいにすれば$でjQueryオブジェクトを参照できるよ
(function($) {
   $.fn.flashBlueRed = function() {
      return this.each(function() {
         var hex = rgb2hex($(this).css("background-color"));
         if (hex == "#0000ff") {
            $(this).css("background-color", "#ff0000");
         } else {
            $(this).css("background-color", "#0000ff");
         }
       });
    };
})(jQuery);
下のように先頭に;を入れるのは、他のプラグインが;忘れてることがあるからその対策
(そんなに遭遇するパターンなのか…)
;(function($){})(jQuery)

17.8  Safely Combining Several Libraries in Your Applications

コードを一つにまとめたい、でも動かなくなる場合もある。
安全策的には使うフレームワークに相当するライブラリは一つに絞ること。
こっから「良きライブラリ」とは何かの話
一つはwindow.onload=function() ...はDOM Level0のイベントで、既にあるイベントを上書きしてしまって動作がおかしくなるので、フレームワークでは使用しない。
もう一つはグローバルな名前空間はできるだけ使わない(何度もでてきたね)
拡張するときはprototypeを使わずに、ライブラリ側で用意されたものを使用しましょう。
直接拡張すると手に負えなくなるのは目に見えている。

"Well-designed libraries are well-tested, and provide a way to report bugs and view existing bugs."
よく使われてるライブラリはバグが見えやすいし、少ないので使うべきって感じ。

まとめ
  • A good library does not use DOM Level 0 event handling.
良きライブラリは、DOM 0イベントは使わない
  • A well-defined library uses object literals to namespace its functionality.
明確なライブラリは、名前空間にオブジェクトリテラルを使い機能を定義している。
  • A well-defined library introduces few global objects.
明確なライブラリは、グローバルなオブジェクトは少ない
  • Libraries that play well with others provide event hooks. Well-behaved libraries also don’t extend existing objects via the prototype property.
行儀良いライブラリは、直接prototypeで拡張させないように、イベントをホックする仕組みを用意している
  • Solid libraries are well-tested, and hopefully provide these self-tests as deliverables.
信頼できるライブラリは、よくテストされていて、望むなら自分自身をテストできる
  • Stable libraries are actively maintained and, preferably, open sourced.
安定したライブラリは、開発やメンテナンスがアクティブで、オープンであることを好んでいる
  • Secure libraries provide documentation of known bugs and problems, and a way to report on any bugs and problems you find.
セキュアなライブラリは、既知のバグや問題が文章化されている。また発見したバグや問題を報告する方法が用意されている。
  • Usable libraries are well-documented. Bandwidth-friendly libraries are optimized and compressed, though you can always compress the library yourself
お手軽なライブラリは、ドキュメントがしっかりしている。
またライブラリを圧縮、最適化することができ帯域に優しい。
  • Confident libraries aren’t built on the assumption that no other library will be used.
将来性のあるライブラリは、他のライブラリと一緒に使われる事を想定している。

まあ著者はjQueryだよって言いたいようだ。
最後のサマリの部分は面白いので、誰かがもっとちゃんとして翻訳をしてくれるはず。

Chapter 16. JavaScript Objects
2010/09/13(月) 24:20 Javascriptはてブ情報 はてブに登録 はてブ数

JavaScriptはprototypal inheritanceを元にした言語。
クラスベースとは違い、最初にクラスを作ることを心配しなくて良い。
オブジェクトは再利用性が高い。

16.1 Defining a Basic JavaScript Object

newとthisキーワードについて。
オブジェクトの初期化(構築)を行う関数をコンストラクタ関数。
コンストラクタ関数にあるthisはインスタンス(実体)を示す。
// コンストラクタ関数
function Tune (song, artist) {
   this.title = song;
   this.artist = artist;
   this.concat=function() {
      return this.title + "-" + this.artist;
   }
}
window.onload=function() {
   var happySong = new Tune("Putting on the Ritz", "Ella Fitzgerald");
   // print out title and artist
   alert(happySong.concat());
}
コンストラクタをnewした時、thisは空のオブジェクト{}を示すので。var happySong = new Tune("Putting on the Ritz", "Ella Fitzgerald");は以下のような感じになる。
var happySong = {
   title  : song,
   artist : artist,
   concat : function() {
      return this.title + "-" + this.artist;
   }
}
newを付けないでTuneを呼んだ場合は、コンストラクタ内のthisはwindowを示すので、windowにメソッドやプロパティが追加されてしまう。
// treating Tune like a function
Tune("the title", "the singer");
alert(window.concat()); // lo and behold,
                        // "the title the singer" prints out
これのthisが示すものをもっとわかりやすくするとwindow.Tuneを呼び出してるので、thisが示すインスタンスはwindowとなっている。
window.Tune("the title", "the singer");
alert(window.concat()); 

16.3 Expanding Objects with prototype

prototypeの追加方法

16.4 Adding Getter/Setter to Objects

getterとsetterの使い方
function Tune() {
    var artist;
    var song;
    this.__defineGetter__("artist", function() {
        return artist
    });
    this.__defineSetter__("artist", function(val) {
        artist = "By: " + val
    });
    this.__defineGetter__("song", function() {
        return "Song: " + song
    });
    this.__defineSetter__("song", function(val) {
        song = val
    });
}
window.onload = function() {
    var happySong = new Tune();
    happySong.artist = "Ella Fitzgerald";
    happySong.song = "Putting on the Ritz";
    alert(happySong.song + " " + happySong.artist);// Song: Putting on the Ritz By: Ella Fitzgerald
}c

16.5  Inheriting an Object’s Functionality

constructor chainingについて。
(正直この継承は手順が複雑すぎるので使いにくい
function oldObject(param1) {
   this.param1 = param1;
   this.getParam=function() {
      return this.param1;
   }
}
function newObject(param1,param2) {
   this.param2 = param2;
   this.getParam2 = function() {
      return this.param2;
   }
   oldObject.apply(this,arguments);// oldに引数を渡して実行
   // thisのコンテキストはparam2と同じになる
   /* ここにoldObjectを書くのと大体同じ
   this.param1 = param1;
   this.getParam=function() {
      return this.param1;
   }
   */  
   this.getAllParameters=function() {
      return this.getParam() + " " + this.getParam2();
   }
}
   newObject.prototype = new oldObject();// 引数はない
   var obj = new newObject("value1","value2");// 一度にまとめて引数を渡したい
   // prints out both parameters
   alert(obj.getAllParameters());

16.6 Extending an Object by efining a New Property

*こんなとこを読むなら、ES5, Property Descriptor解説 - 枕を欹てて聴くを読みましょう。

コンストラクタ関数を変更しないで、新しいプロパティを追加するには
Object.definePropertyを使う。(ECMAScript 5)
まあ普通にドット演算子でプロパティ作ってやることもできますが、definePropertyはプロパティの性質(ここではPropertyDescriptorとしておきます)についても決定できる。
someObject.newProperty = "somevalue";
definePropertyの場合
Object.defineProperties(newBook, {
     "stock": {
        value: true,
        writable: true,
        enumerable: true,
     },
     "age": {
        value: "13 and up",
        writable: false
     }
   });
PropertyDescriptor
  • writable
trueならプロパティ値は変更できる
  • configurable
trueならプロパティは変更削除できる。
falseだとプロパティは削除できなくて、PropertyDescriptor
writable, enumerable, configurable の値を変更できない(プロパティ値の変更はできる)
=>ECMA3 の DontDelete
  • enumerable
trueならイテレート可能(for inで列挙される)
また、defineProperty内でgetterやsetterを決めたときはwritableの設定をすることができません。
 Object.defineProperty(TechBook, "category", {
    get: function () { return category; },
    set: function (value) { category = value; },
    value: "O'Reilly",//デフォルトの値
    enumerable: true,
    configurable: true});
var newBook = new TechBook(...);
newBook.publisher="O'Reilly";
設定されているenumerableなどのPropertyDescriptorの情報は Object.getOwnPropertyDescription を使う事で取得できます。
var propDesc = Object.getOwnPropertyDescriptor(newBook,"category");
alert(JSON.stringify(val)); // {"enumerable":true,"configurable":true}
多少違うけど

16.7  Enumerating an Object’s Properties

オブジェクトがどんなプロパティを持っているか知りたい。
今まではfor...inループを使ってたりしたけど、ECMA5ではObject.keysというメソッドが存在する。
alert(Object.keys(obj).join(", "));
// for ( var prop in obj ) if ( obj.hasOwnProperty( prop ) ) と似たような感じで
getOwnPropertyNamesというメソッドはObject.keysと似ているが、本来なら列挙されないプロパティ(配列のlengthなど)も取得できる。
var props = Object.getOwnPropertyNames(obj);

16.8 Preventing Object Extensibility

ECMA5にはObject.preventExtensionsというオブジェクトの拡張をロックするメソッドがある。
つまりオブジェクトに新しいプロパティやメソッドを追加させなくさせるメソッド
"use strict";
var Test = {
    value1 : "one",
    value2 : function() {
      return this.value1;
    }
};
try {
   Object.preventExtensions(Test);
   // the following fails, and throws an exception in Strict mode
  Test.value3 = "test";
} catch(e) {
   alert(e);
}
既にロックされているかは Object.isExtensibleメソッドで確認できる。
if (Object.isExtensible(obj)) {
   // extend the object
}
(Strict modeどうなるんですかねー

16.9  Preventing Object Additions and Changes to Property Descriptors

Object.preventExtensionsは新たに追加するのを防止するメソッドだったが、PropertyDescriptorの変更をできなくさせるメソッドがObject.sealである。
Object.preventExtensions + configurable:false
"use strict";
 var Test = {
    value1 : "one",
    value2 : function() {
      return this.value1;
    }
  }
  try {
     // オブジェクトをfreezeする
     Object.seal(Test);
     // プロパティは変更できる
     Test.value2 = "two";
     // 追加はできない。 throw an error in Strict Mode
     Test.newProp = "value3";
      // PropertyDescriptorはへんこうできない
     Object.defineProperty(Title, "category", {
         get: function () { return category; },
         set: function (value) { category = value; },
         enumerable: true,
         configurable: true});
   } catch(e) {
      alert(e);
   }
同じようにif (Object.isSealed(obj)) で既に適応されてるかを判定できる。

ECMA3.1の[[Flexible]]はECMA5だと[[configurable]]?

16.10 Preventing Any Changes to an Object

プロパティの追加、変更、削除、PropertyDescriptorの変更などすべてできなくさせるにはObject.freezeメソッドを使う。
"use strict";
  var Test = {
    value1 : "one",
    value2 : function() {
      return this.value1;
    }
  }
try {
  // freeze the object
  Object.freeze(Test);
  // さっきとは違いここでもエラーになる。変更も不可
  Test.value2 = "two";
   // so would the following
   Test.newProperty = "value";
   // and so would the following
   Object.defineProperty(Title, "category", {
      get: function () { return category; },
      set: function (value) { category = value; },
      enumerable: true,
      configurable: true});
} catch(e) {
   alert(e);
}
freezeするとno additions,no changes to existing propertiesになる。
if (Object.isFrozen(obj)) ...で確認。

つまり、Object.seal()、Object.freeze()、Object.preventExtensions() は Object.defineProperty() の糖衣構文 (syntax sugar) だったのだ。そりゃ、機能が制限されていて当然である。
http://end-of-file.net/blog/2008-08.html#date-2008-08-21

16.11 One-Off Objects and Namespacing Your JavaScript

ネームスペースを設けて衝突を防ぐ
var jQuery = {
   //プロパティとかメソッドとか
}
みたいな話です。
グローバルなものは一つか二つぐらいにするってやつ。

16.12  Rediscovering “this” with Prototype.bind

ECMAScript 5にはFunctionオブジェクトにbindというメソッドがあり、thisを設定できる。
   window.name = "window";
   var newObject = {
      name: "object",
      sayGreeting: function() {
            alert("Now this is easy, " + this.name);
            nestedGreeting = function(greeting) {
              alert(greeting + " " + this.name);
            }.bind(this);
            nestedGreeting("hello");
       }
   }
   newObject.sayGreeting("hello");

// 今まではprototype.jsのようにprottotype拡張してた
Function.prototype.bind = function(scope) {
  var _function = this;
  return function() {
    return _function.apply(scope, arguments);
  }
}
特にsetTImeoutとかの時にスコープを設定するのに使う事多い。

16.13 Chaining Your Object’s Methods

メソッドチェーンについて。
メソッドチェーンするにはthisを返すのが定説。
function Book(title, author) {
    var title = title;
    var author = author;
    this.getTitle = function() {
        return "Title: " + title;
    }
    this.getAuthor = function() {
        return "Author: " + author;
    }
    this.replaceTitle = function(newTitle) {
        var oldTitle = title;
        title = newTitle;
    }
    this.replaceAuthor = function(newAuthor) {
        var oldAuthor = author;
        author = newAuthor;
    }
}

function TechBook(title, author, category) {
    var category = category;
    this.getCategory = function() {
        return "Technical Category: " + category;
    }
    Book.apply(this, arguments);
    this.changeAuthor = function(newAuthor) {
        this.replaceAuthor(newAuthor);
        return this;// ここでthisを返してる
    }
}
window.onload = function() {
    try {
        var newBook = new TechBook("I Know Things", "Shelley Powers", "tech");
        alert(newBook.changeAuthor("Book K. Reader").getAuthor());//changeAuthorではnewBookが返るのでチェーンできる
    } catch (e) {
        alert(e.message);
    }
}
メソッドチェーンはコード量が減ったり、まとめて処理を行えるので便利だけどデバッグがしににくなったり読むのに慣れが必要。


短く書き捨てる場合はメソッドチェーンのメリットは光ますが、メソッドチェーンはデバッグを難しくします。 「数分でbugfixしなければ殺される」風味な状況で「メソッドチェーンの部分がネックでデバッグが進まない」という悲惨な状況に10年前遭遇したことがあります。


Twitter / uupaa: 短く書き捨てる場合はメソッドチェーンのメリットは光ま ...



ブラウザ間でちゃんと互換性があれば、かなりかたーいものも書けるようになるはずなんですよね。まだ未実装のブラウザの方が多い話。

Chapter 15. Creating Media Rich and Interactive Applications
2010/09/12(日) 21:32 Javascriptはてブ情報 はてブに登録 はてブ数

SVGとCanvasについて。
SVGはJavaScriptとは独立している。
Canvasの起源はAppleから生まれたもの。

続きを読む

1: dhrname 『失礼して、ご指摘させていただきます。 >excanvas.js >VMLを使ってIEにもSVGを表示 excanvas.js...』 (2011/02/12 19:38)

Chapter 14. Creating Interactive and Accessible Effects with JavaScript, CSS, and ARIA
2010/09/08(水) 23:06 Javascriptはてブ情報 はてブに登録 はてブ数

14.0 Introduction

Accessible Rich Internet Applications (ARIA)
Webはリッチになったのでアクセスビリティを保つためには
音声ブラウザ-スクリーンリーダー。
障害と言ってもいろいろあるが次の範囲をサポートすれば大体OK。
  • 視覚障害 色弱者など
  • 聴覚障害
  • 運動障害 マウスが使えないなど
  • 認識機能障害 アルツハイマーなど
ARIAはHTML5のD&Dイベントについても話し合ってるよ。

14.1 Displaying a Hidden Page Section

Assistive Technology devices - Google 検索AT devices.
要素を隠すときにdisplay:noneとするとドキュメントのレイアウトから完全に消える。
完全に消えるとは、他の要素(子ノードをのぞく)に影響を与えなくなることを指す、visibilityは他の要素に影響を与えるのでレイアウトからは消えてない。
また上記の音声ブラウザのようなATデバイス向けにaria-hiddenという属性が存在する。
aria-hiddenがtrueだと要素は非表示状態であり、読まれません。
falseの場合(デフォルト)要素は表示してあり、読まれます。(音声ブラウザ)
var msg = document.getElementById("msg");
msg.style.display="block";
msg.setAttribute("aria-hidden", "false");
// and hide it, when not:
var msg = document.getElementById("msg");
msg.style.display="none";
msg.setAttribute("aria-hidden", "true");


Q. aria-hiddenが実際のノードの表示、非表示とマッチしないときはどうするか。
A.この誤った状態は確認する必要はない。なぜなら、レイアウトAPIがより完璧な情報を提供する場合、aria-hiddenは必要ない。忠告:aria-hidden="true"を伴った要素が見えるならば、ARIAの間違った使用方法である。aria-hiddenプロパティはDOMベースの支援技術が可視状態の変化の情報を受け取ることができるようにするためのみにエクスポーズすべきである。なぜなら、実際に非表示となっているすべてのノードの最も完全なセットはレイアウトAPIが提供するからであり、aria-hidden属性ではなくそれらを使用すべきである。


WAI-ARIA 1.0 User Agent Implementation Guide



前にも言ってたけど、JavaScriptオフの場合を考えると最初から要素を隠しておくのは適切ではない。

14.2 Creating an Alert Message

AT devicesにもalertするには、要素のrole属性にalertと入れて明示的にすればいい。
The Roles Model | Accessible Rich Internet Applications (WAI-ARIA) 1.0

14.3 Highlighting Form Field with Missing or Incorrect Data

入力ミスを促すエラー表示
onblurに入力をチェックする処理を付ける。
エラーになっているフォームをハイライトするのはよくあること。
またエラーになってるという情報を埋め込むことも大事で、ATデバイスに対してはaria-invalidをtrueにすることでどの要素が間違っているのかを通知できる。
まとめると
  1. エラーになってるフォームを強調+aria-invalid=trueを付ける
  2. submitボタン付近に何がエラーになってるのかを表示
もう一つのアプローチとして、onblurではなくすべてのフォームを埋めてsubmitしたタイミングでエラー表示する事もある。
これはマウスよりもキーボードを主体とする人たちにフレンドリー。
(いちいち表示されるといらいらするって事かな?

14.4 Adding Keyboard Accessibility to a Page Overlay

キーボードのアクセスビリティ。
マウスクリックで写真をlightboxするのと同じ機能を、Enterキーを押した場合にもできるようにしている。またEscキーで戻れるようになっている。
// mouse click on image within link
function imgClick() {
    var img = this.firstChild;
    expandPhoto(img.getAttribute("data-larger"));
    return false;
}
// key press on image within link
function imgKeyPress(evnt) {
    evnt = (evnt) ? evnt : ((window.event) ? window.event : "");
    var keycode = (evnt.which) ? evnt.which : evnt.keyCode;
    if (document.getElementById("overlay")) {
        if (keycode == 27) {//esc
            restore();
            return false;
        }
    } else {
        if (keycode == 13) {//enter
            var img = this.firstChild;
            var src = img.getAttribute("data-larger");
            expandPhoto(src);
            return false;
        }
    }
}
また、lightboxした時画像の tabindex=-1をセットしている。これをすることでキーボードフォーカスをセットしている。

14.5 Creating Collapsible Form Sections

折りたたみフォーム
aria-expanded=falseでたたんだ状態。
function switchDisplay() {
  var parent = this.parentNode;
  var targetid = "panel_" + this.id.split("_")[1];
  var target = document.getElementById(targetid);
  if (this.getAttribute("aria-expanded") == "true") {
    this.setAttribute("aria-expanded","false");
    target.style.display="none";
    target.setAttribute("aria-hidden","true");
  } else {
    this.setAttribute("aria-expanded","true");
    target.style.display="block";
    target.setAttribute("aria-hidden","false");
  }
  return false;
}

14.6  Displaying a Flash of Color to Signal an Action

色の点滅で削除に成功かエラーか。
red:成功、yellow:エラー
要素を色づけしてフェードする。
var fadingObject = {
    yellowColor: function(val) {
        var r = "ff";
        var g = "ff";
        var b = val.toString(16);
        var newval = "#" + r + g + b;
        return newval;
    },
    fade: function(id, start, finish) {
        this.count = this.start = start;
        this.finish = finish;
        this.id = id;
        this.countDown = function() {
            this.count += 30;
            if (this.count >= this.finish) {
                document.getElementById(this.id).style.background = "transparent";
                this.countDown = null;
                return;
            }
            document.getElementById(this.id).style.backgroundColor = this.yellowColor(this.count);
            setTimeout(this.countDown.bind(this), 100);
        }
    }
};
// document.getElementById("one") => fade
fadingObject.fade("one", 0, 300);
fadingObject.countDown();
何か突然bind使ってるのでそのままだと動かないけど。
この色をfadeで変えるとき、原色から白色にするのでは無くて少しずらした値から変化させる方が自然。

14.8 Live Region

定期的にアップデートされるエリアの定義
ARIAではARIA Live Regionsというものがあり、ページをロード後に変化する場所を示せる。
<ul id="update" role="log" aria-alive="polite" aria-atomic="true"
aria-relevant="additions">
</ul>
属性の説明
role=logはアップデートログをpollingする要素に付ける。
aria-liveのエリアがpoliteというのはクリティカルなアップデートではない場所を示す。
aria-live=assertiveは重要な更新場所であることを示し、スクリーンリーダーは作業中の事(他の部分を読み上げなど)を中断してそこ読み上げる。
aria-atomic=trueなら新しく追加された部分だけを読み上げます。falseだと毎回全部読み上げるのでうるさい。
aria-relevantがadditionsに設定(デフォルト)されていると追加の時のみに変化をATデバイスに伝える。他にもremovalsやtext、allがある。
ちょっと他では見かけないAccessible Rich Internet Applications (ARIA)について結構書いてあった章だった。
この著者はアクセスビリティについて結構訴えてる文が多いので、そういう視点でこの本を読むのもありだろう。
またJavaScriptを書いているときにこういう時にどういう名前にするべきかを決めるときにARIAは参考になるかもしれない。

Chapter 13. Working with Web Page Spaces
2010/09/07(火) 25:39 Javascriptはてブ情報 はてブに登録 はてブ数

13.0 Introduction

Webページのスペースの決定要因を学ぶ。
ページフローにある要素によってスペースは決まるが、position: absolute;のようにページフローから外れた場合は影響を与えない。

13.1 Determining the Area of the Web Page

ウィンドウページのwidthとheightを求める。
function size() {
    var wdth = 0;
    var hth = 0;
    if (!window.innerWidth) {
        wdth = (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth);
        hth = (document.documentElement.clientHeight ? document.documentElement.clientWidth : document.body.clientHeight);
    } else {
        wdth = window.innerWidth;
        hth = window.innerHeight;
    }
    return {
        width: wdth,
        height: hth
    };
}
var viewPort = size();
var w = viewPort.width;
var h = viewPort.height;
CSS3はCSSOM View Moduleというもので標準を決めようとしている。

13.2 Measuring Elements

要素の高さを取得するにはgetBoundingClientRectを使う。
var height = 0;
var rect = document.getElementById("it").getBoundingClientRect();
if (rect.height) {
    height = rect.height;
} else {
    height = rect.bottom - rect.top; // derive height
}
alert(rect.height);
このメソッドはIE5からきてCSSOMで標準となろうとしてる。
要素に対して実行するとClientRect objectを返す。
ClientRect objectにはtop, bottom,right,leftが入っていて、Firefoxだとheightとwidthも入っているため計算の必要はない。
要素の大きさはborderまでのサイズとなりmarginは含まれない。これはCSSでも同じ
text->padding->border->margin Chapter 2 ハウ・トゥ編-Theme 010 - prog*sig

13.3 Locating Elements in the Page

要素の位置を取得
同じようにgetBoundingClientRectでleftとtopをとれば、座標となる。
function positionObject(obj) {
   var rect = obj.getBoundingClientRect();
   return [rect.left,rect.top];
}

13.4 Hiding Page Sections

visibility and displayの違い。
visibilityは見えなくても他の要素に影響与える(スペースを持ってる)
display:noneは要素のスペースを取り除くのでリフロー計算が起きる。

13.5 Creating Collapsible Form Sections

必要なものだけ表示して後は折りたたんでおきたい。
clickでdisplayを変化させればいいでないの

13.6 Adding a Page Overlay

overlayする要素を作りたい。
.overlay{
   background-color: #000;
   opacity: .7;
   filter: alpha(opacity=70);
   position: absolute; top: 0; left: 0;
   width: 100%; height: 100%;
   z-index: 10;
}
サンプルがシンプルだけど結構良い感じだ。

13.7 Creating Tab Pages

Tabデザイン
タブはよく使われて有効なデザインだが、ルールがある。
• The highlighted tab is changed to the one just clicked.
• The currently displayed page is hidden or set to nondisplay.
• The clicked tab’s style is changed (so it’s highlighted).
• The associated content page is displayed.
要はクリックできるものは分かるようにする、現在のタブがどれかを分かるようにする。
これ地味に難しい。色分けだけだと見分けで判断できない。

13.8 Creating Hover-Based Pop-up Info Windows

マウスオーバーでポップアップをさせる。
要点を抜き出すと、ポップアップさせたい要素に"mouseover"イベントを付けて、
そのイベントではXHRで情報を取得して、overlay要素をcompPosで取得した位置を元に入れる。
また"mouseout"イベントでは追加した要素を取り除く処置を入れる。
// compute position for pop up
function compPos(obj) {
    var rect = obj.getBoundingClientRect();
    var height;
    if (rect.height) {
      height = rect.height;
    } else {
      height = rect.bottom - rect.top;
    }
    var top = rect.top + height + 10;
    return [rect.left, top];
}
要素位置の章だった。