もうちょっと説明すると
<!doctype html><html><head><title></title> <script src="uu.js"></script> <script src="uu.ev.js"></script> <script src="uu.css.js"></script> <style> div { background-color: red; } .mark { background-color: lime; } </style><script> function boot(uu, $) { uu.exp(); mix(win, { TOP: 1, LIST: 2 }); body(h1(tx("-DEMO-")), div("id:a,class:mark", tx("hover me"), TOP), div("id:b,class:mark", tx("hover me"), TOP, "border:3px solid gray"), div(ul(li(tx("node3-1-1")), li(tx("node3-1-2")), li(tx("node3-1-3"))), "id:c,class:mark", tx("click me"), LIST)); } function looks(uu, $, node, num) { if (num === TOP) { css(node, hash("backgroundColor:skyblue")); } } function feels(uu, $, node, num) { if (num === TOP) { ev.hover(node, function(e) { ev(e).style.color = "red"; }, function(e) { ev(e).style.color = "pink"; }); } if (num === LIST) { ev.times(node, "click", 2, function(e) { ev(e).style.color = "red"; }, function(e) { ev(e).style.color = "pink"; }, function(e) { ev(e).style.color = "white"; }, function(e) { ev(e).style.color = "black"; }); } } </script></head><body></body></html>
ブートローダー
window.boot 関数を見つけると、適切なタイミングでコールバックします。
第一引数には、ライブラリのルートオブジェクト(uu) が、第二引数には jQuery っぽい I/F を提供する uu.jam オブジェクトが渡されます。
// ブートローダー // DOMContetLoaded または window.onload でライブラリから自動的にコールバックされる function boot(uu, $) { }
# 引数で渡すので boot($$, $) とか boot(_, jQuery) など、お好みで。
グローバル名前空間の汚染
お急ぎの方向けに、(グローバル名前空間を犠牲にして)ちゃっちゃと書く方法を提供しています。
uu.exp() を実行すると、uu.xxx を window.xxx にリンクします。
// export namespace
uu.exp();
# ブラウザによっては速度的なメリットもあるようです。
定数の設定
div(...) で利用する番号(1, 2)に名前を与えています。
# 説明のためにこうしてます。実際には要らないといえば要らないです。
// windowオブジェクトに定数を追加 mix(win, { TOP: 1, LIST: 2 });
DOM ツリーの構築
<body>スカスカ</body> な感じのHTML文書を読み込み、body の中身を詰め込む使い方(WebAppとか)を想定した機能です。
body(h1(tx("-DEMO-")), // <h1>-DEMO-</h1> div("id:a,class:mark", tx("hover me"), TOP), // 属性 id="a", class="mark" を設定 div("id:b,class:mark", tx("hover me"), TOP, "border:3px solid gray"), // 直感的にスタイルを設定する方法も提供 div(ul(li(tx("node3-1-1")), li(tx("node3-1-2")), li(tx("node3-1-3"))), { id: "c", className: "mark"}, // 文字列でも hash でもOK tx("click me"), LIST));
テキストノードの生成
tx("テキスト") でテキストノードを生成しています。
例では使っていませんが、 "[テキスト]" でもテキストノードを生成できます。
# 文字列の両端に [ と ] が必要です。[ と ] は除去されます。
ノードの生成
body(), div(), ul(), li() でそれぞれのノードを生成しています。この他にも HTML4 で良く使うタグや HTML5 のタグは一通り使えます。
div() や ul() などは ノード, 数値, 文字列, Hash で構成される可変長引数を受け取り、div ノードを生成します。
- 数値を見つけると、window.looks() と window.feels() をコールバックします(後述)
- 文字列 または Hash なら、一つ目を属性値(node.attr)として、二つ目をスタイル値(node.style)として扱います。
- ノードを見つけると、appendChild します。
ルックス(style)とフィーリング(event)の設定
window.looks() と window.feels() は、ノード生成時にコールバックされるユーザ定義関数です。
div() だとコールバックしません。div(1) のように番号付きで指定すると looks(uu, uu.jam, node, 1) の形で呼び出します。
ルックス(style)の設定は window.looks() で行います。
# div("", "color:red") とすることで DOM ツリー構築と一緒にスタイルを設定することもできます
// ノード生成時に、スタイルを設定する機会を提供する function looks(uu, $, node, num) { if (num === TOP) { css(node, hash("backgroundColor:skyblue")); } }
uu.hash() は 文字列/Hash/Array から Hash を生成する関数です。
フィーリング(event)の設定は window.feels() で行います。
// ノード生成時に、イベントを設定する機会を提供する function feels(uu, $, node, num) { if (num === TOP) { ev.hover(node, function(e) { ev(e).style.color = "red"; }, function(e) { ev(e).style.color = "pink"; }); } if (num === LIST) { ev.times(node, "click", 2, function(e) { ev(e).style.color = "red"; }, function(e) { ev(e).style.color = "pink"; }, function(e) { ev(e).style.color = "white"; }, function(e) { ev(e).style.color = "black"; }); } }
uu.ev.times() は イベントを期限付きで定義する関数です。この例では、4 x 2 = 8回クリックすると無効になります。
uu.ev() は イベントオブジェクトをクロスブラウザ対応にする関数です。
# ピーキーなイベント(ドラッグ&ドロップ等)でモッサリさせないため、イベントオブジェクトを常に加工するようなことはしていません。必要なら加工して使います。
# uu.event ではなく uu.ev という名前になっているのは、IE と Opera が window.event を予約しているからです。uu.exp でexport すると衝突してしまいます(気づくのが遅かった)
汚染
去年は「名前空間を汚染しない/させない方法」ばかり求めてましたが、最近は「名前空間を汚染する/しないはユーザが決めることだ」と考えを変えました。
もちろん名前空間を汚染しなくてもスッキリ書けますよ。
汚染あり
var cv; body(header(), nav(), article(section(), section()), aside(cv = canvas("width:300,height:150")), footer()) var ctx = cv.getContext("2d"); ctx.fillRect(...)
汚染なし
var cv; uu.body(uu.header(), uu.nav(), uu.article(uu.section(), uu.section()), uu.aside(cv = uu.canvas("width:300,height:150")), uu.footer()) var ctx = cv.getContext("2d"); ctx.fillRect(...)
余談
"[テキスト]" を使うと、ちょっと節約できます。
tx("テキスト") - 233 byte
body(h1(tx("-DEMO-")), div("id:a,class:mark", tx("hover me"), TOP), div("id:b,class:mark", tx("hover me"), TOP, "border:3px solid gray"), div(ul(li(tx("node3-1-1")), li(tx("node3-1-2")), li(tx("node3-1-3"))), "id:c,class:mark", tx("click me"), LIST));
"[テキスト]" - 219 byte
body(h1("[-DEMO-]"), div("id:a,class:mark", "[hover me]", TOP), div("id:b,class:mark", "[hover me]", TOP, "border:3px solid gray"), div(ul(li("[node3-1-1]"), li("[node3-1-2]"), li("[node3-1-3]")), "id:c,class:mark", "[click me]", LIST));
"[テキスト]" のほうが見やすいかも。