tohokuaikiのチラシの裏

技術的ネタとか。

prototype.jsのgetElementsByClassNameがFireFoxとI.Eの互換性うんぬんでややこしいので、なんとかしてみる。


FireFox3になってから、getElementsByClassNameがNativeSupportされたので、I.Eとの互換性がメンドイよねっていう話。

とりあえず、

<body bgcolor="#cccccc">
<ul>
<li class="b">bbb</li>
</ul>
<ul id="hoge">
<li class="a">1</li>
<li class="b">2</li>
<li class="c">3</li>
<li class="d">4</li>
<li class="e">5</li>
</ul>
</body>

っていうHTMLがあった場合、

$('hoge').getElementsByClassName

は、IE/FFどちらでもちゃんとFunctionとして定義される。それは、$関数が最後にElementをElement.extend(element)ってやって返しているから、Element.getElementsByClassNameが生きてくるというのが理由。

だけど、当然

    var x = $('hoge').getElementsByTagName('LI');
    for (var i=0,j=x.length; i<j; i++){
        console.log(typeof(x[i].getElementsByClassName));
    }

なんてやった場合は、IEはundefinedを返す。

じゃあってんで、

    var x = $('hoge').getElementsByTagName('LI');
    for (var i=0,j=x.length; i<j; i++){
        document.getElementsByClassName("targetClassName", x[i]);
    }

なんてやっちゃうと、Firefoxでは第ニ引数が意味をなさなくって、Documentオブジェクト全体から"targetClassName"なクラス名のDOMをとってきちゃう。I.Eだと、prototype.jsで定義されたgetElementsByClassNameが立ち上がるから、予想通りの結果が得られる。


困ってしまう。

ので、domにgetElementsByClassNameが無い場合は、明示的にprotoytpe.jsのgetElementsByClassNameを使うように

    var x = $('hoge').getElementsByTagName('LI');
    for (var i=0,j=x.length; i<j; i++){
        var e = x[i].getElementsByClassName ?
                   x[i].getElementsByClassName("targetClassName") :
                   Element.getElementsByClassName(x[i], "targetClassName");
    }

としてしまう。

ただ、これ注意しないとなのは、document.getElementsByClassNameと引数の順番が逆なんだよね。

しかも、prototype.jsのマニュアルみると、非推奨メソッドになってる。

しかも、何とかしてみるとか言って、分岐かよっていう・・・・。