DOM Future と DOM の将来
DOM Future
と DOM の将来
わかば (id:wakabatan)
DOM Future
と DOM の将来
- DOM 現代史のつまみぐいです
- 紹介する新機能はまだ実装されていないかもしれません
- 5年後くらいには普通に使えるようになっている、かも
DOM Standard の歴史
- 2007年 しばしば「DOM5」が必要だと囁かれるようになる
- DOM3 が現状と乖離しており、メンテナンスもされていなかった
- 2008年 「Web DOM Core」
- 2010年 「Web DOM Range」
- 2011年 「Web DOM Core」が W3C WebApps WG へ
- Events、Traversal が追加される
- Web DOM Range が統合される
- 「Web DOM Core」→「DOM Core」→「DOM4」
- 2012年 「DOM4」が WHATWG へ
- 「DOM Standard」
- HTML 同様の Living Standard 開発モデル
- W3C DOM4 は WHATWG DOM Standard のスナップショットコピーに
DOM3 から変わったこと
- あらゆる規定が明確になった
- DOM3 はリファレンスマニュアルレベルでとても曖昧だった
- ブラウザ実装との違いや矛盾が解消された
- 実装されていない機能はばっさり削除されている
EntityReference
や CDATASection
も廃止
- いくつかの新機能
もっと JavaScript っぽく
// DOM
new Document
new Text ("Hoge")
new MouseEvent ("click", {bubbles: true, view: window})
// DOM2
document.implementation.createDocument (null, null, null)
document.createTextNode ("Hoge")
ev = document.createEvent ("MouseEvent"); ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
exception.name === 'HierarchyRequestError' // DOM
exception.code === exception.HIERARCHY_REQUEST_ERR // DOM1-3
object.addEventListener ("click", function (ev) { ... }) // 第3引数は省略可能に
MutationObserver
- DOM 木に変化があった時にコールバックが呼び出される
- 失敗作だった DOM3 mutation event のかわりに追加された
var observer = new MutationObserver (function (records) {
...
});
observer.observe (element, {childNodes: true, characterData: true});
新しい木操作メソッド
element.append ("Hoge", childElement1, childElement2, "fuga");
element.appendChild (document.createTextNode ("Hoge"));
element.appendChild (childElement1);
element.appendChild (childElement2);
element.appendChild (document.createTextNode ("fuga"));
element.before (childNode, "text");
element.parentNode.insertBefore (childNode, element);
element.parentNode.insertBefore (document.createTextNode ("text"), element);
node.after ("text", childNode);
node.replace ("hoge");
node.remove ();
Future
- 今年追加された
- 「実行中かこれから実行されるかもう実行完了した操作の結果への非同期アクセス」
- promise, deferred, thenable などと呼ばれているものと同じ
Future
使わない例
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
if (xhr.responseText == '') {
alert ('error');
} else {
var xhr2 = new XMLHttpRequest ();
xhr2.open ('GET', xhr.responseText, true);
xhr2.onreadystatechange = function () {
if (xhr2.readyState == 4) {
if (xhr2.status == 200) {
step3 ();
} else {
alert ('error');
}
}
};
xhr2.send (null);
}
} else {
alert ('error');
}
}
};
- コールバックの入れ子でコードが右にのびていきがち
- 深いコールバックでエラーが起こったことを浅い方にどう伝えたらいいかよくわからない
- 複数のコールバックの結果を待って何かしたいときどう書いたらいいのかよくわからない
Future
使った例
xhr.send ().then (function () {
if (xhr.status == 200) {
if (xhr.responseText == '') {
throw "error";
} else {
return xhr.responseText;
}
} else {
throw "error";
}
}).then (function (path) {
var xhr2 = new XMLHttpRequest ();
xhr2.open ('GET', path, true);
return xhr2.send (); // Future を返す
}).then (function () {
step3 ();
}).catch (function (e) {
alert (e.name);
});
.then() .then() .then() ...
と書き連ねていける
- 前の
.then
のコールバックで返した値が次の
.then
のコールバックに伝わる
Future
を返せば、その Future
の結果を待つ
- 例外を投げれば
.catch
のコールバックに伝わる
「実行中かこれから実行されるかもう実行完了した操作」
document.ready().then(...)
navigator.geolocation.getCurrentPosition().then(...)
indexDB.open(name).then(...)
new Future (function (resolver) {
if (...) {
resolver.accept(...);
} else {
resolver.reject("error");
}
}).then(...)
Future
の組み合わせ
Future.any(future1, future2, ...).then(...)
Future.some(future1, future2, ...).then(...)
Future.every(future1, future2, ...).then(...)
Future.every(fetchJSON("/user/mario"), fetchJSON("/user/luigi")).done(
function(mario, luigi) { ... },
showFailcat
)
DOM の将来
- JavaScript との親和性をより高く
- よく使う操作をより簡単に
- ... という方向性は今後も続いていきそう
node.on("click", function () { ... })
???
- E4H ???
function addCheckbox(name, label, checked, enabled) {
return @<label><input type="checkbox" name={name}
checked?={checked} disabled?={!enabled}/>
{label}</label>;
}
- ECMAScript の人達に評判が良くないので当面はなさそう