愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

iPhone/Android向けのselector-based libraryを実装しての色々(1)

selector-based libraryってまず何やねん、って話ですが、いわゆる$("#id")みたいにcssセレクタでelementをモリっと引っ張ってきて、そのwrapされたelement集合に生えてる関数でいろいろやることがメインの目的とされてるJavaScriptライブラリのことを僕はそう呼んでいます。

まあ、いわゆるjQueryとかprototypeとかです。cssセレクタ+αでオマケユーティリティとかはついてるけど、モジュールを定義する機能とか、モジュール間の依存性を解決しつつそれらをロードする機能とか、コンポーネントを作成する機能とか、そういうのがついてないイメージ。

で、なんで僕がselector-basedなライブラリを書いてしまったかというと、とある人とラーメン屋で「スマホ向けのJSライブラリって、なんか一度それ使っちゃうとそれ以外で書けなくなっちゃう(ライブラリに激しくlock-inされちゃう)ようなものが多いけどそういうのあんまり使いたくないよねー。なんかいいのない?」という話をして、個人的にiPhone/Androidのブラウザ向けのJSが書いてみたかったこともあって、「エイヤッ!」という感じですね。つまり、ノリです。


ちなみにこれです。

http://github.com/zentooo/Riddle.js


コンセプトを書くと

  • ある程度最近のiOSAndroidで動けばいい。他は知らない
  • コアは出来るだけ小さく、だが必要十分な便利さを
  • やたらに関数呼び出しを重ねない(読みにくいから、あと一応、遅いから)
  • 可能なら速いほうがいいが、最適化するためにやたらコードが長くなるとか、煩雑な処理が必要になる場合は多少遅くなっても簡潔な方を選ぶ
  • コードが簡潔になる && 現在主流のiOS/Android versionで動くことが保証されている ならば、非標準のAPIの使用は厭わない(outerHTMLとか)

という感じです。

分かる人は分かると思いますが、だいたいZeptoのコンセプトと近いです。じゃあなんでZeptoがあるのにわざわざ書いたの?って話ですが、それはZeptoのコードがイケてないからです。


githubのほうにも書いてありますが、日本語で、かつ補足しつつ機能を書くと

  • r({fucntion}) でDOMContentLoadedが呼ばれた後にコールバック関数を呼ぶ
  • r({string}, {HTMLElement, NodeArray})で、いわゆるcssセレクタでelementを引っ張ってきて、ラップしたobjectを返す。(NodeArrayはそのラップしたオブジェクトの便宜的な型)
  • NodeArrayに対するhtml, add, remove。addは第二引数で挿入位置を指定できる
  • NodeArrayに対するattr, css, addClass, removeClass, hasClassなどの操作
  • NodeArrayに対するevent binding (bind, unbind, click, submit, focus, ... )
  • NodeArrayに対する便利関数 ( detect, invoke, pluck )
  • xhrのラッパ (r.ajax)
  • r.id, r.clsなど、getElementByIdやgetElementsByClassNameなどを使ったより高速なクエリー (Zepto同様、cssセレクタ部分についてはquerySelectorAllに投げてサボっている。ので、idとかclassでもっと速く引くための関数)

などなど。ノリが分り易いようにある程度まではjQuery互換ですが、完全互換を目指す気はなく、機能は絞っています。実装にあたっては、jQuery, uupaa.js, Zeptoなどを参考にしました。


使ってみた例の人いわく「けっこう便利」とのことなので、小さいかつまあまあ便利なのではないかと思います。酔狂な人は試してみて下さい。バグ報告歓迎です。


なんか長くなったので、実装によって得られた少々の知見とか、testとかdocumentとかについては次回。