Kanasan.JS JavaScript 第 5 版読書会 #62008年11月21日 21時40分

Kanasan.JS JavaScript 第 5 版読書会 #6 に行ってきました (当日のチャットログ参加者のブログ一覧)。今回は 14 章「ブラウザウィンドウの制御」から 16 章「CSS とダイナミック HTML」の途中まで読み進めました。

タイマーの仕様 (14.1、p. 282)

setTimeout などのタイマーはブラウザが独自に実装したもので、標準化された仕様は存在しません。HTML 5 の草案には一応含まれているものの、独立した仕様に移すことが示唆されています。かといって、その場合の受け皿となるであろう W3C WebApps WG にもはっきりとした動きは見られず (Apple の人から高精度タイマーの提案が出ていましたが)、タイマーの標準化がどうなるのかよくわかりません。

Navigator オブジェクト (14.3.3, p. 289)

Navigator オブジェクトを基にブラウザを判別して動作を変えるのはよくないという話。ただし、例外としてあるブラウザの特定バージョンのみに存在するバグに対処する場合が挙げられています。あるメソッドが存在しないというのならまだいいのですが、メソッドは存在するけど動作が異なるとなったら苦労しますからね。

window.open の引数 (14.4.1, p. 292)

window.open メソッドは第3引数にウィンドウの表示情報などを渡せますが、これは "width=400,height=350" といった文字列を使って指定します。これに対して、文字列だといかにも格好悪いから、オブジェクトリテラルを使って { width: 400, height: 350 } のように指定できないのかという声がありました。しかし、window.open メソッドが導入されたのが JavaScript 1.0 (NN 2、このころは JavaScript の言語機能とブラウザのオブジェクトモデルが分離されていませんでした)、対してオブジェクトリテラルの導入が JavaScript 1.2 (NN 4) と、歴史的経緯で文字列指定になっていると思われます。

window のメソッドと document のメソッド (14.4.2, p. 293)

window オブジェクトにも document オブジェクトにもそれぞれ open、close メソッドが存在しますが、それらの動作は異なります。open() とだけ書いた場合、外部ファイルまたは script 要素内にスクリプトを書いていれば、グローバルオブジェクトである window オブジェクトの open メソッドと解釈されます。しかし、<input onclick="open()" /> のように HTML のイベントハンドラ属性にスクリプトを書いた場合、スコープチェーンに document オブジェクトが含まれ、document オブジェクトの open メソッドと解釈されることがあります。このような場合には、明示的に window オブジェクトを指定しなくてはいけません。

window.onerror (14.7, p. 300)

window.onerror に関数を設定すると、すべてのプログラムの最上位に try-catch 文があるかのように振舞います。例外が発生したがそれより上位に try-catch 文がないときに、onerror に設定した関数が呼び出されるのです。とはいえこれは JavaScript に try-catch 文がなかったころの遺物であり、try-catch 文が広く使える今日では利用する機会はほとんどないでしょう。

frames プロパティ (14.8.2, p.303)

その文書が含むフレームの集合を得るために frames プロパティがありますが、実は Firefox、IE、Safari では window オブジェクトの frames プロパティはその window オブジェクト自身を指します。なので、window.frameName として参照できるものは window.frames.frameName としても参照できますし、window[i]i 番目のフレームを取得可能。さらには frames.setTimeout() なんてこともできます。

要素への名前付け (15.3.1, p. 317)

HTML には name 属性が存在しますが、その意味は要素によって異なります。

  1. 要素の名前を表すもの (a 要素、img 要素、form 要素など)
  2. フォームコントロールの名前を表すもの (input 要素、textarea 要素、select 要素、button 要素)

このうち、1 については今や name 属性を使う必要はなく、id 属性を使うべきです。

getElementsByClassNameメソッド (15.6, p. 335)

Firefox 3、Safari 3.1、Opera 9.5 以降では getElementsByClassName メソッドが実装されていますが、これは引数として指定されたクラス名をすべて含むクラス名を持つ要素を取得します。引数として指定されたクラス名と一致するクラス名を持つ要素のみではありません。getElementsByClassName("a b") とすれば、class 属性の値が "a b"、"b a"、または "a b c" などである要素は取得できますが、class 属性の値が "a" である要素は取得できません。

JavaScript のソートアルゴリズム

JavaScript のソートアルゴリズムは実装依存であり、安定性も要求されません。SpiderMonkey の場合、バージョン 1.7 以下 (Firefox 2 以下) ではヒープソートを使っていましたが、やはり安定なソートのほうがいいとのことでバージョン 1.8 (Firefox 3) ではマージソートに変更されました。JavaScriptCore では場合によって選択ソート、マージソート、クイックソートのいずれかが、V8 ではクイックソートと挿入ソートの組み合わせが使われるようです。

unicode-bidi CSS プロパティ (16.1, p. 365)

unicode-bidi CSS プロパティ (bidi は biderectional の略か?) は、Unicode の双方向書字アルゴリズムに関する制御文字の扱いを指定するためのプロパティです。双方向書字アルゴリズムに関しては HTML にも bdo 要素があります。

「控えめな JavaScript」? (16.2.2, p. 375)

CSS を使った影つきテキストの生成が「控えめな JavaScript」の例として出てきますが、これは同じ内容を持つ要素を CSS の位置指定で重ねるというもので、同書で控えめな JavaScript の 3 番目の目標として挙げられていたアクセシビリティを低下させないということに反する気がします。音声ブラウザの例を取り上げなくとも、コピーアンドペーストの際などに意図した結果が得られなくなりますし。

雑感

思い起こせば 1 年前、第 1 回 Kanasan.JS に参加したのをきっかけにさまざまな人と出会え、関西での活動の場を広げられたと思います。その Kanasan.JS を立ち上げた Kanasan さんが関東に引っ越すとのことで、今回を最後に運営スタッフから抜けることになってしまいました。他の運営スタッフの方々が後を引き継ぐとのことですが、全員で同じものを読み進めていくという勉強会のスタイルを確立し、ここまで続けてこられたのはやはり Kanasan さんの力によるところが大きいでしょう。これまで本当にありがとうございました。

誰が AutoPagerize を提供すべきか2008年11月25日 13時00分

はてなブックマークがリニューアルしました。新しいはてなブックマークの個人ページにはページ自動ロード機能、通称 AutoPagerize 機能 (そう呼んでいる人がどれだけいるかは知りませんが) がついています。さて、AutoPagerize のような一般の Web ページにも適用しうる機能は誰が提供すべきでしょうか。ページの製作者でしょうか? ユーザー側が (ブラウザの拡張機能も含む) ユーザースクリプトとして導入すべきでしょうか? はたまたブラウザ側の仕事でしょうか? Twitter 上でそのことに関するやり取りがあったので少しまとめてみました。

hotchpotch
bbeta ってデフォルトで AutoPagerize ついてるんだ。変なボタン押すと有効になるっぽい(haihai sakura sakura) (2008-11-10 11:50)
os0x
はてなブックマークβ の AutoPagerize SITEINFO どうしたものかね。個人的にはサイト側で用意されている機能を優先したい。 (2008-11-10 18:10)
サイト側で(Greasemonkey の)AutoPagerize をブロックできる仕組みがあればいいのかな。 (2008-11-10 18:31)
nanto_vi
@os0x AutoPagerizeに限らずユーザースクリプトと製作者スクリプトの競合を解決する仕組みが作れればいいんですけどね。 (2008-11-10 18:36)
製作者スクリプトは<meta name="UserSideAutoPagerize" content="no" />を生成する、AutoPagerizeはそのようなmeta要素があったら停止する、というのを思いついた。 (2008-11-10 18:42)
http://nanto.asablo.jp/blog/2008/08/02/3668606 の延長線上の話で。 (2008-11-10 18:42)
meta要素生成だとユーザースクリプトを強制することができないけど。 (2008-11-10 18:44)
os0x
metaタグで拒否Script名を書くと、それにマッチするユーザースクリプトは実行されないとか。名前変えればいいだけだけど、それぐらいで丁度良さそうな気がする。 (2008-11-10 18:43)
@nanto_vi 見事に同じことを考えてました。 (2008-11-10 18:53)
AutoPagerizeについていえば、製作者スクリプトとして提供されたほうが望ましいと思う。わざわざ SITEINFO なんて用意しないといけないのは、製作者がやることを強引にユーザースクリプトで対応しようとしているからだし。 (2008-11-10 18:56)
kanasan
@nanto_vi autopagerizeをsite側で切れるようになると、ニュースサイトは全滅しそう。page viewが稼げないから...。 (2008-11-10 18:54)
nanto_vi
@kanasan あー、「ユーザースクリプトのAutoPagerizeを使わない」と「製作者スクリプトのAutoPagerizeを使う」を同一視してました。この二つは別物でしたね。 (2008-11-10 23:21)
hotchpotch
AutoPagerize が入っていればデフォルトで有効にしたいなー。 (2008-11-10 20:18)
snj14
@os0x AutoPagerizeはユーザスクリプトでやるべきじゃないってのには同意.ただ,製作者スクリプトでやるってのには同意できないです.あれはブラウザが標準でやるべきことだと思います.ブラウザの標準機能でナビゲートされることを期待されていたrel-nextなんかと一緒. (2008-11-11 00:21)
os0x
@snj14 ブラウザが提供するなら、OperaのFast Forwardぐらいになると思います。 http://labs.gmo.jp/blog/ku/2007/10/operafast_forward.html AutoPagerizeみたいなページ壊しちゃう機能をブラウザが実装ってのはあんまり現実的じゃないかと。 (2008-11-11 00:28)
snj14
@os0x Siteinfoなんて物を用意しないといけないのは別の問題で,ページを機械的に操作されることを予期せずにフリーダムにマークアップしても「人間が見えればオッケー」な風土を作った誰かが悪くて,rel-nextを考えたような人の描いた通りになってれば問題無かったと思います. (2008-11-11 00:29)
@os0x ページなんて,コンテンツを表示するためのガワでしかないのだから,ぶっ壊れようがなにしようが,コンテンツさえ見えれば(それが本来の目的なのだから)全然問題無いと思ってます. (2008-11-11 00:35)
@os0x あ,ちょっと違いました.本来の目的はコンテンツを見ることによって情報を得るだとか,楽しむだとか,そういうことです.そのための手段としてコンテンツを見ます.ページはそのコンテンツを表示するための手段です.本来の目的により近い部分が達成されれば下位はどうでも良いかと. (2008-11-11 00:42)
os0x
@snj14 その発想はユーザー側の発想で、コンテンツ提供者の意見も取り入れないといけないブラウザの立場ではないと思います。確かにユーザーの目的は常に情報を得ることですが、提供者側の目的は様々です。 (2008-11-11 00:46)
snj14
@os0x コンテンツ提供者はユーザでもあります.メモをWeb上に取っておいて読み返す人なんて典型的です.ユーザの目的を多く達成することを優先するほうが理に叶ってると思いますが.逆に,ページレイアウトが崩れて困る人ってどういう目的の人でしょう? (2008-11-11 00:54)
os0x
@snj14 すみません、コンテンツ提供者と製作者(サイトオーナー)が混ざってました。ここでは製作者側、特に個人ではなく企業とかでサイトを作っているケースを考えています。 (2008-11-11 01:35)
@snj14 Twitterとかはてなとかlivedoorとか各種ニュースサイトとかのことです。 (2008-11-11 01:37)
@snj14 ただでさえ日ごろクロスブラウザには手を焼いているのに、ブラウザの機能でページが崩れることを容認できるとは思えません。製作者は可能な限り自分達の管理下に置きたいと考えます。実際、はてなもそうなんだと思います。 (2008-11-11 01:47)
指定パスのDocumentを取ってきて表示するとかone linerで出来て、AutoPagerみたいなのも数行で実現できるようなブラウザってのが現実的な落とし所なのかなぁ。 (2008-11-11 02:44)
いや、それが標準化されてなきゃ意味ないか。 (2008-11-11 02:45)
hotchpotch
@os0x レイアウト崩れる、デザインの見せ方以外にも、スターなどのJS周りの付与なんか(APがfilter でできるようなJSの実行)もしたいというのがありますね。 (2008-11-11 08:48)
snj14
@os0x 企業の目的ってのは,ページを壊さないことでなくて,利益(利潤?)を得ることの筈.利益を得る為の手段としての広告が,とかページビューが,とかの話ならば,広告やらの「ユーザから嫌われるもの」を守ってまでユーザの体験が正当に進化しないのは企業にしたって本意でないと思います. (2008-11-11 22:34)
@os0x 客でもあるユーザに嫌われる役を買ってまで今の広告スタイルを守らなくても,コンテンツと広告の距離がもっと近く(今のgoogleのやつよりも.)なれば,adblock使ってまで対策を取るようなことにはならないし,その方が広告効果も見込めそうな気がしてならないのですが. (2008-11-11 22:44)
@os0x そして,ユーザの興味を持つコンテンツに近い広告効果のあるナニカを作ったとして,そのユーザに届けるためには,ユーザに関する機械可読なデータ(その人が何に興味を持つのか,等)が必要不可欠であると思います.なので,ユーザに機械可読なアウトプットをさせる必要があります. (2008-11-12 00:34)
@os0x ユーザにアウトプットさせるためには(そしてそれを持続可能にするためには),軽い,面倒臭くない,AutoPagerizeのような,TomblooのようなUIが必要だと思います. (2008-11-12 00:43)
@os0x なので,今すぐ利益があるとは言えませんが,AutoPagerizeのようなUIをブラウザ側で実装することではてな等が未来永劫不利益を被る,ということにはならないとおもいますし,むしろ,適当にそれっぽく表示している今より良くなると思ってます. (2008-11-12 00:53)
たぶんだけど,Siteinfoもちゃんと考えてSemanticWebの方向に持っていくと,Trustとかの層まで来て,人の繋がりの情報を持った方が精度があがっていって.スパムがどうとか考えなくてすむようになるんじゃないカナー (2008-11-12 01:18)
os0x
@snj14 ブラウザ側AutoPagerizeはWEB製作を難しくしてしまいます。セマンティック・ウェブは特に、ですね。メリットがあることは理解できるけど、正直なところ現実的な方法とは思えないんです。 (2008-11-12 01:25)
@snj14 逆に、いわゆるデータマイニング的な手法のほうが現実的で、将来性があるんだろうと思います。 (2008-11-12 01:28)
@snj14 実際、履歴データだけでもそれなりのレコメンデーションは実現できています。情報が足りなくて精度が低いなら、幾つかの選択肢を用意すればユーザーが選んでくれます。 (2008-11-12 01:35)
(つい、話がレコメンデーションに。。) (2008-11-12 01:36)
@snj14 それで、ブラウザ側で実装されちゃうとコッチ(製作者)でコントロールできなく(し難く)なるので、歓迎できないって感じです。だから、AutoPagerizeが簡単に実現できるブラウザなら大歓迎です。 (2008-11-12 01:39)
bulkneets
@os0x それが当然になったなら、それに合わせてビジネスモデルとか作るモンじゃないの (2008-11-12 01:47)
os0x
@bulkneets そうなったらそうでしょうね。ただ、現状でも自前で実装してAutoPagerが活きるビジネスモデルは出来ますね。身も蓋もないけど、広告も挿入されるとか。 (2008-11-12 01:58)
なんだかんだ言って、ブラウザが実装するAutoPagerizeのイメージが湧いてきた。少し手を動かしてみるか。 (2008-11-12 02:21)
まだ出来は良くないとはいえ Google Chrome に Greasemonkey が乗ったから、Safari が追従することが期待できるし、ブラウザの標準機能になる可能性も見えてきた。 (2008-11-14 02:37)

AutoPagerize に関していうなら、個人的にはこれはユーザースクリプト、またはデフォルトで無効にされたブラウザ組み込みの機能 (私はこの二つにあまり違いを感じません) として提供されるべきだと思っています。文書内容をじかにいじるものをブラウザが提供し、さらにそれをフォルトで有効にするというのには少々抵抗を感じます。

「少々抵抗を感じます」という言葉で濁しましたが、これは私の中で考えがまとまっていない部分です。突き詰めれば単に今までブラウザにそのような機能が提供されてこなかったからという慣れの問題のような気がします。ですからこれから Web に触れる人には関係ありませんし、私自身そういう機能がデフォルトで提供されれば案外すんなりと受け入れるのではないかとも思います。かつての iCab はデフォルトで accesskey 属性の値を要素の右肩に表示していました (iCab が独自エンジンから WebKit に鞍替えした現在、この機能が提供されているのかは知りません)。私はこの表示方法を受け入れ、素晴しいと思ったのですから。

SITEINFO をどうするかという問題はありますが、上のやり取りで言及されていた Opera の Fast Forward の仕組みや本文抽出モジュール (ちなみにそこで紹介されている Perl モジュールは第 1 回はてなインターンの成果が基になっています) などを組み合わせれば、意外と多くのページで期待通り動くのではないかと思います。HTML 5 が正しく運用されればそんなヒューリスティックに頼る必要も減るでしょうし。

しかしながら、はてなブックマークのように製作者側でプラスアルファの機能をつけたいということもあります。ユーザースクリプトと製作者スクリプトでは、CSS のように、重要指定付きユーザースクリプト、製作者スクリプト、通常のユーザースクリプトと排他的な優先順位を設定する仕組みが整っていればいいと言いましたが、CSS のようにという観点からすれば排他的な部分の粒度はもっと細かくして全体としては多層的、すなわちユーザースクリプトの動作を製作者スクリプトがフックできるような仕組みが望ましいのではないかと思います (現状の AutoPagerize でも、DOMNodeInserted イベントを監視し、それらしき要素が挿入されたらといった具合にフックすることは可能でしょうが)。