UserAgentを使わないブラウザ判定を作った

これ。例のIE5+も動くjQuery用。winieとmacieとunknownを追加した。

昼間載せたバージョンはIE5だと動作しなかった。IE5ではObjectの添え字は文字列だけのようだ。switchを使った実装に変えて回避。

チェックはあまり終わっていない。

チェックしたブラウザ

  • Windows Vista
    • IE 5.5 (IE Tester)
    • IE 6 (IE Tester)
    • IE 7 (IE Tester)
    • IE 8b1 (IE Tester)
      • 7と判定(Selectors APIが未実装っぽいから)
    • Opera 8.0
    • Opera 9.52
    • Fx 2.0.0.16
      • 20080702と表示(Fx3と混同しそうだけど、Fxは実装バグが少ないから多分使わない
    • Safari 3.1.2 (525.21)
      • 3と判定
  • Windows 2000

名前空間のケチり方

jQueryの現在のコードだと、

window.$ = function () {
	return new $.prototype.init();
};

$.prototype = {
	init: function () {
		// コンストラクタ
	}
};

$.prototype.init.prototype = $.prototype;

こういう風にやっている。僕はあまり好きじゃない。できれば、initで分けたくないし、最後の一行の突っ込むのも気色悪い。

そんなわけで古いコードに当たってみた。1.2.1はこんなのだった。

window.$ = function () {
	return this instanceof $ ? this.init() : new $();
};

$.prototype = {
	init: function () {
		// コンストラクタ
	}
};

ここで見たコードによく似ている。arguments.calleeは使いたいところだけど、IE5が対応していないので、残念。

1.2まではこうなっていた。

window.$ = function () {
	if (this == window || !this.init)
		return new $();
	return this.init();
};

$.prototype = {
	init: function () {
		// コンストラクタ
	}
};

this.initがあるのはthis==windowがtrueにならないIE対策っぽい。でも、window.window==windowだから、

window.$ = function () {
	if (this.window == window)
		return new $();
	return this.init();
};

$.prototype = {
	init: function () {
		// コンストラクタ
	}
};

こうでもいける。

個人的にはinstanceofに惹かれるんだけど、変わった1.2.2のリリースノートには300% Speed Improvements to $(DOMElement)ってあるから、これのために変わったのかと思っている。そう思ったけど、全然関係なかった。ベンチとったけど、差はない。早くなったのは、DOMElementの時は別処理になったため。