SSブログ

all [JavaScript]

document.all プロパティ/メソッド

  1. collection = document.all;
  2. allcollection = document.all;
  3. element = document.all.id;
  4. element = document.all[index];
  5. element = document.all[id];
  6. collection = document.all[name];
  7. nodelist = document.all[name];
  8. element = document.all(index);
  9. element = document.all(id);
  10. element = document.all(name);
  11. collection = document.all(name);
  12. nodelist = document.all(name);

なんじゃこら。

形をピックアップするだけでも大変だわ。

指定された DOM(Document Object Model) 形式のドキュメント document に対して、以下の動作をします。

  1. Internet ExplorerOpera がこの形。document 内のすべてのエレメントに対する Element クラス(またはそのサブクラス)のコレクション collection HTMLCollection)を返す。ただし、Internet ExplorerOpera では、格納されている情報が異なる場合があるので、要注意。
  2. SafariGoogle Chrome がこの形。document 内のすべてのエレメントに対する Element クラス(またはそのサブクラス)のコレクション allcollection HTMLAllCollection)を返す。
  3. id プロパティが id であるエレメントへの参照 element を返す。
  4. document 内のインデックス値が index であるエレメントへの参照 element を返す。ただし、Internet Explorer と他のブラウザでは、格納されている情報が異なる場合があるので、要注意。
  5. id プロパティが指標値(文字列) id であるエレメントへの参照 element を返す。
  6. Internet ExplorerOpera がこの形。name プロパティが指標値(文字列) name の複数のエレメントのコレクション collection HTMLCollection)を返す。
  7. SafariGoogle Chrome がこの形。name プロパティが指標値(文字列) name の複数のエレメントのノードリスト nodelist NodeList)を返す。
  8. document 内のインデックス値が index であるエレメントへの参照 element を返す。ただし、Internet Explorer と他のブラウザでは、格納されている情報が異なる場合があるので、要注意。
  9. id プロパティが引数(文字列) id であるエレメントへの参照 element を返す。
  10. Internet Explorer のみ、この形。name プロパティが引数(文字列) name のうち、最初のエレメントの参照 element を返す(模様)。
  11. Opera のみ、この形。name プロパティが引数(文字列) name の複数のエレメントのコレクション collection HTMLCollection)を返す。
  12. SafariGoogle Chrome がこの形。name プロパティが引数(文字列) name の複数のエレメントのノードリスト nodelist NodeList)を返す。

Firefox 系は動きません。

Firefox くらい、態度がはっきりしててくれると、まだ助かるんだけどね。

なんなの? このブラウザごとのバラバラ加減。

はっきり言って、こういう存在は、JavaScript の「癌」です。

【追記】 2010/12/29 22:03 検証したブラウザのバージョンを追記します。
Internet Explorer 8Firefox 3.6.13Opera 11.00Safari 5.0.3Google Chrome 8.0.552.224

 「それでも使いたい」という方のために、注意点をピックアップします。


document.all の型

document.all は、ブラウザによって型が違います。

Internet Explorer Opera では HTMLCollectionSafari Google Chrome では HTMLAllCollection です。

ただし、双方に共通するメンバ(lengthitemnamedItemtags など)は、問題なく使えます。

HTMLCollection HTMLAllCollection については、いずれエントリーにします。

これらのメンバについては、そのエントリーで取り上げます。


◆複数のエレメント参照を返すオブジェクト インスタンスの型

複数のエレメント参照を返すオブジェクト インスタンスの型も、ブラウザ依存です。

Internet Explorer Opera では HTMLCollectionSafari Google Chrome では NodeList です。

Opera の場合、getElementsByTagNamegetElementsByName では NodeList を返すのに、ここでは HTMLCollection を返すんですよね。

ふしぎ!


◆指定可能なエレメントのパラメータ

取得したいエレメントでパラメータに指定できるのは、document 内でのエレメントのインデックス値 index、取得したいエレメントの id プロパティ id、取得したいエレメントの name プロパティ name のいずれかです。

id プロパティ id については、document.all.id; と記述する方法、document.all[id]; と記述する方法、document.all(id); と記述する方法の3通りが可能です。

tagName プロパティは指定できません。

これは、どのブラウザでも同じです。

tagName プロパティ tagname を使用したいときは、HTMLCollection または HTMLAllCollection tags メソッドを使います(document.all.tags(tagname) のように)。

この document.all.tags メソッドを使用した場合、各ブラウザに依存する戻り値の型で、指定したタグのエレメント参照を一気に返してきます(Internet Explorer HTMLCollectionOpera TagsArraySafari Google Chrome NodeList)。

詳細は、いずれ HTMLCollection または HTMLAllCollection のエントリーで取り上げます。


◆インデックス値で操作する場合の注意点

Internet Explorer だけは、DOCTYPE 宣言やコメントもエレメントとしてカウントします(DOCTYPE 宣言もコメントとみなします)。

他のブラウザは、これらをエレメントとしてカウントしません。

従って、Internet Explorer と他のブラウザの間では、document 内でのエレメントのインデックス値 index にズレが発生することがあります。


◆name プロパティを指定した時の、プロパティとメソッドの動作の違い

これに該当するのは、Internet Explorer で、取得するエレメントの name プロパティ name を指定したときだけです。

エレメントの name プロパティ name を指定した場合、プロパティ アクセスとメソッド呼び出しで結果が異なります。

プロパティ アクセス collection = document.all[name]; の場合、複数のエレメント参照を一気に返す HTMLCollection を返してきます。

一方、メソッド呼び出し element = document.all(name); の場合、同じ name プロパティを持つエレメントが複数あっても、返してくるのは HTMLCollection ではなく、ひとつのエレメントに対する Element サブクラスの参照です。

この場合、(試した限りでは)もっともインデックス値の小さいエレメントのみを返してくるようです。

Internet Explorer 以外の対応ブラウザは、プロパティでもメソッドでも、コレクション collection か、ノードリスト nodelist を返してくるので、動作に差異はありません。


俺なら、絶対に getElementByIdgetElementsByTagNamegetElementsByName を使うわ。

たとえタイプ量が増えても。

と、いうわけで。

今回の検証ソースです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>document.all</title>
    <script type='text/javascript'>
    //<![CDATA[

        // 環境エラー
        function errorEnvironment() {
            alert('ご使用の環境では、このスクリプトはご使用できません。');
        }

        // 任意のオブジェクトのすべての属性を列挙
        function enumAllProperties(refObject) {
            // 引数:refObject ... 属性を列挙したいクラス
            // 戻値:String ...... 属性の列挙結果文字列(ひとつ1行で改行をはさむ)
            var strProperties = "";
            for (var item in refObject) {
                strProperties = (strProperties + item + " = " + refObject[item] + "\n");
            }
            return strProperties;
        }

        // イベントを追加する addEvent
        window.addEvent = function (evt, func, cap) {
            if (window.addEventListener)
                window.addEventListener(evt, func, cap);
            else if (window.attachEvent)
                window.attachEvent('on' + evt, func);
            else
                alert('ご使用の環境では、このスクリプトはご使用できません。');
        }

        // ウィンドウ ロード イベント onWindowLoad
        function onWindowLoad(evt) {

            // all が有効か調べる
            try {

                // 検証開始メッセージ
                alert('document.all メンバの検証を開始します。');

                // メンバでなにが使える?
                alert('メンバでなにが使える?:\nenumAllProperties(document.all):\n' + enumAllProperties(document.all));
                // 結果:見てあげて!

                // length 使える?
                alert('length 使える?\ndocument.all.length:\n' + document.all.length);
                // 結果:ie,op,sa,gc:ok

                // item 使える?
                alert('item 使える?\ndocument.all.item:\n' + document.all.item);
                // 結果:ie,op,sa,gc:ok

                // namedItem 使える?
                alert('namedItem 使える?\ndocument.all.namedItem:\n' + document.all.namedItem);
                // 結果:ie,op,sa,gc:ok

                // tags 使える?
                alert('tags 使える?\ndocument.all.tags:\n' + document.all.tags);
                // 結果:ie,op,sa,gc:ok

                // プロパティで探す
                alert('プロパティで探す:\ndocument.all:\n' + document.all);
                // 結果:HTMLCollection(ie,op)/undefined(ff)/HTMLAllCollection(sa,gc)

                // プロパティで探す(length)
                alert('プロパティで探す:\ndocument.all.length:\n' + document.all.length);
                // 結果:13(ie)/exception(ff)/10(op,sa,gc)

                // プロパティで探す(id 直接)
                alert('プロパティで探す:\ndocument.all.id_btn1.value:\n' + document.all.id_btn1.value);
                // 結果:HTMLCommentElement(ie)/HTMLHtmlElement(op,sa,gc)

                // プロパティで探す(インデックス値 [0])
                alert('プロパティで探す:\ndocument.all[0]:\n' + document.all[0]);
                // 結果:HTMLCommentElement(ie)/HTMLHtmlElement(op,sa,gc)

                // プロパティで探す(インデックス値 [1])
                alert('プロパティで探す:\ndocument.all[1]:\n' + document.all[1]);
                // 結果:HTMLHtmlElement(ie)/HTMLHeadElement(op,sa,gc)

                // プロパティで探す(インデックス値 [2])
                alert('プロパティで探す:\ndocument.all[2]:\n' + document.all[2]);
                // 結果:HTMLHeadElement(ie)/HTMLTitleElement(op,sa,gc)

                // プロパティで探す(パラメータ [id])
                alert('プロパティで探す:\ndocument.all["id_btn1"]:\n' + document.all['id_btn1']);
                // 結果:HTMLInputElement(ie,op,sa,gc)

                // プロパティで探す(パラメータ [tag name])
                alert('プロパティで探す:\ndocument.all["input"]:\n' + document.all['input']);
                // 結果:undefined(ie,op,sa,gc)

                // プロパティで探す(パラメータ [name])
                alert('プロパティで探す:\ndocument.all["name_radio"]:\n' + document.all['name_radio']);
                // 結果:HTMLCollection(ie,op)/NodeList(sa,gc)

                // プロパティで探す(パラメータ [name].length)
                alert('プロパティで探す:\ndocument.all["name_radio"].length:\n' + document.all['name_radio'].length);
                // 結果:3(ie,op,sa,gc)

                // プロパティで探す(パラメータ [name][1].value)
                alert('プロパティで探す:\ndocument.all["name_radio"][1].id:\n' + document.all['name_radio'][1].id);
                // 結果:id_radio_2(ie,op,sa,gc)

                // 関数で探す(パラメータ [インデックス])
                alert('関数で探す:\ndocument.all(0):\n' + document.all(0));
                // 結果:HTMLCommentElement(ie)/HTMLHtmlElement(op,sa,gc)

                // 関数で探す(パラメータ [id])
                alert('関数で探す:\ndocument.all("id_btn1"):\n' + document.all('id_btn1'));
                // 結果:HTMLInputElement(ie,op,sa,gc)

                // 関数で探す(パラメータ [tag name])
                alert('関数で探す:\ndocument.all("input"):\n' + document.all('input'));
                // 結果:null(ie,op)/undefined(sa,gc)

                // 関数で探す(パラメータ [name])
                alert('関数で探す:\ndocument.all("name_radio"):\n' + document.all('name_radio'));
                // 結果:HTMLInputElement(ie)/HTMLCollection(op)/NodeList(sa,gc)

                // 関数で探す(パラメータ [name])
                alert('関数で探す:\ndocument.all("name_radio").id:\n' + document.all('name_radio').id);
                // 結果:id_radio1(ie)/undefined(op,sa,gc)

                // 関数で探す(パラメータ [name])
                alert('関数で探す:\ndocument.all("name_radio").length:\n' + document.all('name_radio').length);
                // 結果:undefined(ie)/3(op,sa,gc)

                // 関数で探す(パラメータ [name])
                alert('関数で探す:\ndocument.all("name_radio").value:\n' + document.all('name_radio').value);
                // 結果:Radio Button 1(ie)/undefined(op,sa,gc)

            }

            catch (e) {

                // 無効のアラート メッセージ
                alert('例外がスローされました');
            }

            finally {

                // 検証終了メッセージ
                alert('document.all メンバの検証を終了しました。');
            }
        }

        // 唯一の初期化処理
        window.addEvent('load', onWindowLoad, true);

        //]]
    </script>
</head>
<body>
    <!-- ボタン -->
    <input type="button" id="id_btn1" name="name_input" value="Button1" />
    <input type="button" id="id_btn2" name="name_input" value="Button2" />

    <!-- ラジオボタン -->
    <input type="radio" id="id_radio1" name="name_radio" value="Radio Button 1" />
    <input type="radio" id="id_radio2" name="name_radio" value="Radio Button 2" />
    <input type="radio" id="id_radio3" name="name_radio" value="Radio Button 3" />
</body>
</html>

おまえら、そろそろ互換性の高いブラウザ作ってくれや。


nice!(2)  コメント(4)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 2

コメント 4

HOKUTEN

みみちゃん、FF使って曽根風呂の管理画面で、サイドバーを編集しようとすると枠が飛んで行っていじれないのはスクリプトが悪いんですかね。
そこだけいじるのにIE立ち上げるって言うのが・・・(--;
まぁ、曽根風呂はFF推奨じゃないからな・・・。
by HOKUTEN (2010-12-30 01:44) 

みみちゃん

どもです。
ほぼ99%、スクリプトの初期化ミスだと思います。
どっちにしろ表示するものは HTML なんでしょうが、サイドバーの名前の上にカーソルを持っていくと、リンク先が javascript:createPanel( ・・・ ) と出てくるんですね(Firefox の場合)。
だから、名前からしてこの javascript:createPanel メソッドで編集パネルの HTML を動的に作ってるんだと思いますが、そこで表示位置の初期化を「おざなり」にしてるんじゃないかと思います。
利用規約上、リバースエンジニアリング禁止なので、あんまり深入りできないんですけども;;;。
by みみちゃん (2010-12-30 09:18) 

HOKUTEN

アクセス解析だと、IEが50%FF30%ですね。
過半数とはいえ、たったの半分のみが推奨対象ってちょっとねぇ・・・。
クロムも出てきたし・・・。
まぁ、IEの挙動が嫌いな点と、色の表示がおかしい点があるのでIEは嫌いです。
カラープロファイルを無視しているんじゃないかって言う印象が大きい・・・。
マックIEは違うんですけどね・・・。なぜだか・・・。
by HOKUTEN (2010-12-30 15:41) 

みみちゃん

ナイショですけどw、Firefox のための対策とか、やってるみたいなんですよ。
ところが、そういう配慮は最低限「動く」ためのものでしかなくて、「ブラウザごとの共通の挙動」「使い勝手」という点にはケアしてないみたいです。
俺も Firefox 使いだから、こっちで無償でデバッグしてやりたいくらいです;;;。
by みみちゃん (2010-12-30 21:02) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

getElementsByNamealert ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。