Operaのバグ

3日前の記事があまりにも見にくく、また、ちょいとググったりフォーラムで検索してみたところ、既存の報告にはなかったような雰囲気なので、清書しておく。見つけられなかっただけ、という可能性はかなりある(特にフォーラム)。

概要

Opera9.24において、id属性が指定されたdiv要素の直下にコメントがある場合、document.getElementById()関数は、コメント内容をidとして認識し、引数が一致すれば、そのコメントオブジェクトを返す。

発生条件

HTMLソース http://cobodo.hp.infoseek.co.jp/opera/test1.htm

<html>
<head>
<title>opera test 1</title>
<script type="text/javascript">
<!--
function init () {
    alert(document.getElementById('elem1'));
    alert(document.getElementById('elem2'));
    alert(document.getElementById('elem3'));
    alert(document.getElementById('elem1').tagName);
    alert(document.getElementById('elem2').tagName);
    alert(document.getElementById('elem3').tagName);
}
// -->
</script>
</head>
<body onload="init()">
<div id="hoge">
<!--elem1-->
 <div id="elem1"></div>
</div>
<div>
<!--elem2-->
 <div id="elem2"></div>
</div>
<!--elem3-->
<div id="elem3"></div>
</body>
</html>

の場合、IE6では

[object]
[object]
[object]
DIV
DIV
DIV

Firefoxでは

[object HTMLDivElement]
[object HTMLDivElement]
[object HTMLDivElement]
DIV
DIV
DIV

Operaでは、

[object Comment]
[object HTMLDivElement]
[object HTMLDivElement]
undefined
DIV
DIV

と表示される。
document.getElementById()の返り値は、DOM (HTML) Level1DOM Level2 CoreDOM Level3 Coreのいずれにしても Element であり、 Comment は返せない。また、 Comment のインターフェイスにはフィールドが一切無く、属性を持てない。2007/11/16修正*1従って、document.getElementById()は "[object Comment]" を返してはならないはず。

細かいこと

Operaのdocument.getElementById()は、id属性が指定された要素の中にあるコメントの、"<!--"の直後から"-->"の直前までのすべての内容をidとして指定すると、そのコメントオブジェクトを返す。
以下のソースの場合、alertの内容はすべて"[object Comment]"である。

<html>
<head>
<title>opera test 2</title>
<script type="text/javascript">
<!--
function init () {
    alert(document.getElementById('comment'));
    alert(document.getElementById('comment '));
    alert(document.getElementById(' comment'));
    alert(document.getElementById(' comment '));
    alert(document.getElementById('com\
ment'));
}
// -->
</script>
</head>
<body onload="init()">
<div id="hoge">
<!--comment-->
<!--comment -->
<!-- comment-->
<!-- comment -->
<!--com
ment-->
</div>
</body>
</html>

教訓

  • 最初と最後にスペースを含むidは使わない(普通使わないけど)
  • "<!--"の直後と"-->"の直前には、スペースを入れておく

最後に

Operaに報告するのが面倒なので、既出じゃなかったら誰かタレこんでおいてください(ぉ

追記

d:id:quaa:20071201:p1でタレこんでくれたようです。
ってここに書かなきゃいかんことに気づいた12/13の今日(´・ω・`)

*1:色々とフィールドを継承していた。attributesもNodeから継承している。しかしattributesはElement以外ではnullらしい。じゃぁElementで定義しろよ……とも思うが、少なくともこの記述は間違いだった。