Opera9.5+ DocumentFragment 経由でノードを追加すると再描画しない
ノードをDOMツリーに追加するには、2つの異なる方法がありますが、
- DocumentFragment 経由で追加する方法 (method1)
- 直接追加する方法 (method2)
Opera9.5以降でDocumentFragmentを経由すると画面が再描画されません。
# Opera9.52, Opera9.61 で現象を確認済み。Opera9.27やその他のブラウザでは問題なし。
以下は、method1 と method2 のテストコードです。
<html><head><title>uupaa.js - uu.node.substance test</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script src="uu.node.substance_opera95bug.js"></script> </head><body> <input type="button" value="method1" onclick="method1()" /> <input type="button" value="method2" onclick="method2()" /> <input type="button" value="show" onclick="show()" /> <div id="result" style="background-color: silver"></div> </body></html>
// uu.node.substance_opera95bug.js function method1() { var html = '<p style="color: red">hello</p>'; var result = document.getElementById("result"); var rv = document.createDocumentFragment(), ph = document.body.appendChild(document.createElement("div")); // placeholder ph.innerHTML = html; while (ph.firstChild) { rv.appendChild(ph.removeChild(ph.firstChild)); } ph.parentNode.removeChild(ph); // remove placeholder result.appendChild(rv); } function method2() { var result = document.getElementById("result"); var p = document.createElement("p"); var txt = document.createTextNode("hello"); p.appendChild(txt); p.style.color = "red"; result.appendChild(p); } function show() { if (/Gecko\//.test(navigator.userAgent)) { HTMLElement.prototype.__defineGetter__("outerHTML", function() { var r = document.createRange(), tub = document.createElement("div"); r.selectNode(this); tub.appendChild(r.cloneContents()); return tub.innerHTML; }); } var d = window.open().document; d.write("<xmp>" + document.body.outerHTML + "</xmp>"); d.close(); }
Opera9.5+ 以外のブラウザではmethod1とmethod2ボタンは同じ結果になりますが、
Opera9.5+では、何度 method1ボタン を押下しても(DOMツリーには追加されてるが)描画が更新されず、method2を押下すると一気に登場します。