LoginSignup
2
1

More than 5 years have passed since last update.

参考メモ/innerHTMLとdocument.writeのhookついて昔のメモ

Posted at

1-2年ほど前にinnerHTMLとdocument.writeを自前のfunctionに差し替えられないか(=hook)とか、どういうコードで呼ばれるのか調べたメモ。

WebブラウザとJSの世界で1-2年ほど前となると、もう昔の話になる上、なぜそもそもそんなことを調べようとしたのかも忘れてしまったので、単なる参考メモです。

今回Qiitaにメモ整理する際に、メモに残ってたコード断片を動かしてみた検証ブラウザバージョン:

  • Chrome 49
  • Firefox 45
  • IE 11
  • Edge 25

window, window.document

window がブラウザ上でJavaScriptを動かす時の、省略時のグローバルスコープ。

参考:

document.write() はイベントハンドラでは使わない

イベントハンドラ中でdocument.write() を使うと新しいドキュメントを生成してしまうので、画面がクリアされてしまう:

例えばWeb画面のレンダリングが終わった後に、開発者コンソールを開いて document.write('hello'); など打ち込むと、検証環境のすべてのブラウザで画面が真っ白になり "hello" と表示される。

なんかメモに、「イベントハンドラからのフローでdocument.writeが出てくる懸念は無くなった。」と書いてるので、なんか、でてきたらまずいようなの作ろうとしてたのかも。

document.write() を入れ替える

var oldw = document.write.bind(document);
document.write = function() { console.log("hello"); oldw("fuga"); }
document.write();

検証環境すべてで、上記3行を一回実行するだけに限定すれば、動くことは動く。ただし複数回呼び出した時にどうなるかや、他への副作用については不明。

自分でもなぜこのトピックを調べたのか忘れた、参考リンクメモ

多分、innerHTMLを独自関数でhookしようとしていろいろググってたっぽい。

ChromeとinnerHTMLについてのメモ

メモしてた当時、ChromeのinnerHTMLについてちょっと特殊な状況があったらしい。

innerHTMLはElement.prototypeのプロパティではなくて、Elementオブジェクトのプロパティになってるのが、Chrome独自過ぎるのでやめよう、Element.prototypeに移そう、というので進行中(当時は)。

20160327_innerHTML_chrome49.png

20160327_innerHTML_ff45.png

20160327_innerHTML_ie11.png

→今はChromeでもElement.prototypeのプロパティになったのかな?IE系は謎。

document.createElement()をhookすれば、innerHTMLから呼ばれないか?→呼ばれない。

document.createElement() をhookしてみる:

var ce = document.createElement;
document.createElement = function(tagname) { console.log("hooked"); return ce.call(document, tagname); };
var b = document.createElement("b");
b.innerHTML = "<i>abc</i>";
document.getElementsByTagName("body")[0].appendChild(b);

検証ブラウザすべてで、BタグをcreateElement()した時は "hooked" と表示された。しかし innerHTML プロパティにsetした時は "hooked" は表示されなかった。

おそらく innerHTML はnativeコードを参照しているため、hookされたcreateElement()は呼び出していない。

関連参考リンク:

でも、innerHTMLはsetterなので、上記が落ち着くまでは、

var hoge = xxxxx.__lookupSetter__("innerHTML");
hoge.call(element, "<b>hoge</b>");

みたいになる心配は無さそう。プロパティだしこれも無いかな。

プロパティとして一般に使うのであれば xxxxx.innerHTML=<string> 形式で使うのは同じなので、多分この形式を探してブレークを仕掛けられれば捉えられると思う(←結局何をしたかったのか?)。


多分今なら、「how to hook Element innerHTML property」とか、「how to hook document.write」とかでググればいろいろ出てくるのではないか。それで何を作ろうとしていたのか忘れてしまったけれども・・・。なんだろ、仕事に関連した一種のJavaScriptのプロファイラでも作ろうとしてたのかな?

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1