読者です 読者をやめる 読者になる 読者になる

anti scroll

ブラウザと小説の新しい関係を模索する

Matt-Esch/virtual-dom覚え書き

こちらの記事で知ったのですが、Reactで言うところのpropsしかないvirtual dom実装とのこと。

github.com

まさに探していたものなので、さっそく試してみたのですが、以下は覚え書きです。

escapeさせたくない中身はattributesinnerHTMLを設定

inlineなタグでも、そのまま設定するとエスケープされてしまうので。

h("div", "<b>escaped!</b>"); // タグ文字はエスケープされる
h("div", {innerHTML:"<b>not escaped!</b>"}); // innerHTMLなら、そのまま出力される

datasetはdata-xxじゃなくて、dataset:{xx:10}

attributesに直に設定しても動きません。dataset属性にオブジェクトとして設定します。

h("a", {"data-id":10}, "click me"); // NG
h("a", {dataset:{id:10}}, "click me"); // OK

差分パッチの対象から外す要素はtype:"Widget"

中身のDOMElementはinitコールバックで出力します。

h("div", {
  type:"Widget",
  init:function(){
    var dom = document.createElement("div");
    dom.innerHTML = "my custom element!";
    return dom;
  }
});

ev-xxxDOMDelegatorインスタンス化していないと動かない。

attributeにev-(event名)で書きますが、ソースのどこかでnew DOMDelegator()していないとイベント通知は動きません。

var _delegator = new DOMDelegator(); // ev-*を使うには、このインスタンス化が必要
h("a", {
  "ev-click":function(ev){
    alert("clicked!");
  }
});

すこし気になったのは、ev-clickreturn falseしても、クリックの戻り値として反映されないところです。

inlineスタイルの書き方

style内部もオブジェクト(camel-case)で書く。

// NG!
h("span", {style:"font-size:0.5em"}, "small!");

// OK
h("span", {style:{fontSize:"0.5em"}}, "small!");

attribute(properties)の書き方

hrefとかはそのままでいいけど、labelタグのforとかはhtmlForとかだったりする。

h("a", {href:"yahoo.co.jp"}, "yahoo!"); // OK
h("label", {for:"foo!"}, "label for foo!"); // NG!
h("label", {htmlFor:"foo!"}, "label for foo!"); // OK

inputのvalue属性は最後に書く

virtual-domのinput要素を作成する時は、value属性は最後に記述する。

そうしないと、表示する際にレースコンディションが発生して、正しくvalueが反映されないことがあることが知られている。

Input type range control has wrong value on initial render · Issue #228 · Matt-Esch/virtual-dom · GitHub

// NG: 時々valueが正しく反映されないことがある
h("input", {
  type:"range",
  value:200,
  min:10,
  max:100
});

// valueは最後に書く
h("input", {
  type:"range",
  min:10,
  max:100,
  value:200 // 最後に!
});