js-html - JavaScriptを用いたHTMLの省略記法

動機

最終更新
2003-11-18T22:05:42+09:00

次のHTML文書の断片をDOM APIを利用して生成してみます:


<div class="container" id="foo">
  <h2>だいあろぐ</h2>
  <label>
    <input type="button" onclick="alert(true)" />
  </label>
</div>

実際にやってみると次のようになります(一例)。

var div = document.createElement('DIV');
var h2 = document.createElement('H2');
h2.appendChild(document.createTextNode('だいあろぐ'));
div.appendChild(h2);
var label = document.createElement('LABEL');
var input = document.createElement('INPUT');
input.type = 'button';
input.addEventListener('click', function(){alert(true)}, true);
label.appendChild(input);
div.appendChild(label);

この面倒くささ、視認性の悪さを何とかしようというのが主な動機です。尚、addEventListnerの部分はブラウザによっては別の方法にしなければなりません。そして、そういったブラウザ毎の差異を吸収する目的もあります。上記のコードは生成過程であって、HTMLの実体を表すものではありません。従って、生成過程が対応ブラウザ等々によって異り、それぞれに対応する場合、コードから実体を読み取ることは非常に困難になります。

具体例

最終更新
2003-11-29T23:01:16+09:00

空要素

var br = { br: null }; // (1)

br要素を、JavaScriptのオブジェクトリテラル{ key: 値 }で抽象的に表現しています(js-html)。key が要素名、値がその内容です。空要素の場合はnullです。

属性を持った要素

href属性を持ったa要素(<a href="http://example.com" title="example.com">example.com</a>)は次のように表現します。


var a = {
  a: "example.com", // (1)
  $attrs: { href: "http://example.com", title: "example.com" } // (2)
};
  • 要素の子供が唯一つのテキストノードの場合、その文字列が値になります。
  • 属性がある場合、要素名keyと並べて、$attrs keyを定義します。値は属性名 keyとその値の「辞書」になります。

Note

class属性だけは、$attr: {"class": "date"} のように、クォーテーションで括る必要があります。JavaScriptの予約語「class」と衝突する為です。

単一の子を持った要素

<div><h1>spam</h1></div>:

var div = {div: {h1: "spam"} };

複数の子を持った要素

li要素を二つ持ったul要素は次のように表記できます。


var ul = {
  ul:
    [
      { li: "item1" },
      { li: "item2" }
    ]
};
bulider.feed(ul);
builder.build();

ある要素ulに複数の子要素liがある場合、ul key の値は配列になり、配列のアイテムとして、同様に抽象化したliを列挙します。

混合内容

<p>きみの論文は<em>危険</em>だよ、ロージャ。</p>を表現してみます。


var p = {
  p:
   [
     "きみの論文は",
     { em: "危険" },
     "だよ、ロージャ。"
   ]
}

イベントハンドラ

イベントハンドラは属性として扱い、値に関数オブジェクトを指定します。


var button = {
  button: "私は何者",
  $attrs: { onclick: function(){alert(this.nodeName);} }
}

コメント、処理命令

コメントと処理命令は、特別なkey、$comment、$pi を使います。


var comment = { $comment: "コメントです。" }
var pi = { $pi: "target content" }

というか$piは使わないでしょう。

構造

最終更新
2003-11-18T22:06:04+09:00

PrimalNode ::= ElementExpr | CommentExpr | PIExpr
ElementExpr ::= '{' ElmentName ':' ElementValue (',' AttrSet)? '}'
ElementValue ::= Children | Node
Node ::= PrimalNode | String
Children ::= '[' Node (',' Node)* ']'
AttrSet ::= '$attrs' ':' '{' AttrExpr (',' AttrExpr)* '}'
AttrExpr ::= AttrName ':' ( String | Function )
CommentExpr ::= '{' '$comment' ':' String '}'
PIExpr ::= '{' '$pi' :' String }'

ElementName は要素名、AttrNameは属性名です。それぞれHTMLの仕様に準じます。

Stringは、JavaScriptの任意のStringオブジェクトです。内容の制限はHTMLの文法に準じます。

FunctionはJavaScriptの任意の関数オブジェクトです。これはonclick属性等のイベントハンドラにのみ適用されます。

実装例

最終更新
2003-11-18T22:06:04+09:00

HTMLBuilderで js-html を具体的なHTMLに変換できます。