IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

IE の innerHTML や appendChild で要素が挿入された瞬間を取得する方法

要素が挿入された瞬間を取得する

今までは出来ないと思っていたのですが、今日いろいろ試していて出来る方法が分かりました。
ですので、ちょっと紹介したいと思います。今のところアイデアなので、実用性は?です。


方法

HTML に以下の style 要素を挿入することで実現することができます。

<style type="text/css">
* {
    display: expression(function() {
        if (!this.__mark) {
            this.__mark = true;
            alert('inserted node: ' + this.tagName);
        }   
        return ''; 
    }.apply(this));
}
</style>

実際に例を見てみましょう

http://amachang.art-code.org/ieexpression/000.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>IE Rendering Test</title>
<style type="text/css">
* {
    display: expression(function() {
        if (!this.__mark) {
            this.__mark = true;
            alert('inserted node: ' + this.tagName);
        }   
        return ''; 
    }.apply(this));
}
</style>
</head>
<body>
    <input type="button" value="appendChild" onclick="document.body.appendChild(document.createElement('div'))" />
    <input type="button" value="innerHTML" onclick="document.body.innerHTML += 'aaa<br />'" />
</body>
</html>

解説

  • 要素が新しく挿入される
  • レンダリングエンジンは CSS の値を新しい要素に割り当てようとする
  • その際に expression がプロパティ値に設定れていると、その JavaScript 式をその場で実行しようとする。
    • そのときのスコープは onclick 属性などと同じ
  • expression に JavaScript の関数を指定しておいて、 this (その要素)を apply して
  • 関数の中で、一度見た要素に印を付ける
  • 印の付いてない要素は、新しく作られた要素!

という仕組みです。

まとめ

CSS expression 面白いです。
もちろんまともな CSS パーサーだとエラーになります。
なので、気になる人は条件コメントを使うなどしたほうがいいかもしれません。