50
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScript: getElementById()メソッドを使わずにid属性値で要素を参照する

Last updated at Posted at 2018-05-08

Twitterのタイムラインで、つぎのような情報に接しました。このふるまいについての日本語の説明が、検索しても見当たらなかったので、調べたことを簡単にまとめます。

#要素をid属性で参照してみる
まずは、論より証拠で試してみましょう。要素のid属性値をあたかも変数のように参照して、テキストを加えます。すると、たしかに空の要素にテキストが差し込まれるのです。

<body>
<div id="element"></div>
<script>
element.textContent = '参照できた!!';
</script>
</body>

ただし、JavaScriptコードでid属性値と同じ識別子(変数や関数)を定めれば、そちらが優先です。つぎのコードでは、新たにつくって加えられる子要素(<h1>)に、テキストが与えられます。

const element = document.createElement('h1');
document.getElementById('element').appendChild(element);
element.textContent = '参照できた!!';

また、id属性で直に要素を参照するやり方は、Internet Explorer 8では使えないようです。

#id属性値はドキュメントのグローバルなプロパティとして扱われる
要素のid属性値はドキュメントのグローバルな名前空間(Windowオブジェクト)のプロパティとして扱われ、その要素が参照されます(HTML 5.2仕様§6.3.3.「Named access on the Window object」後掲邦訳参照)。けれど、前述のとおり、JavaScriptコードの識別子の方が優先されました。さらに、グローバルプロパティの座を争う識別子は、ほかにもあるのです(たとえば、要素のname属性)。

そのためHTML 5.2仕様は、id属性から要素を参照するには、document.getElementById()メソッドの使用が望ましいとしています(§6.3.3.)。興味深いふるまいではあるものの、豆知識にとどめておくのがよさそうです。

####§6.3.3. Windowオブジェクトへの名前による参照(HTML 5.2)

window[name]
指定された要素または要素の集合を返します。
一般に、これに依存したコードは脆弱になります。 どのidがこのAPIにマッピングされることになるかは、ときとともに変わります。たとえば、Webプラットフォームに新しい機能が追加された場合などです。 代わりに、document.getElementById()document.querySelector()をお使いください。
(筆者邦訳)

#別要素のname属性に同名の値を与えてみる
前項でお話は終わってはいます。ただ、要素によってはname属性値がやはりグローバルで参照できます。一応、それも試しておきましょう。

name属性がグローバルで参照される要素のひとつは<form>です。前掲の<body>要素にこれを加え、name属性値をあえてもうひとつの要素のid属性値と同じにします。

<div id="element"></div>
<form name="element"></form>

console.log()メソッドでこの識別子を参照すると、Chromeのコンソールにはつぎのように出力されました。要素がふたつとも含まれているようです。

HTMLCollection(2) [div#element, form, element: div#element]

試しに以下のJavaScriptコードを試すと、ふたつの要素にテキストが加えられました(ECMAScript 2015の新しいArray.from()メソッドの使い方については「ECMAScript 6のArrayに関わる構文を試す」をお読みください)。

DIVが参照できた!!
FORMが参照できた!!

Array.from(element).forEach((element) =>
    element.textContent = element.nodeName + 'が参照できた!!');

なお、筆者のmacOS環境では、Safariは同じ結果を示したものの、Firefoxではid属性の備わる要素のみが参照されました。HTML 5.2仕様§6.3.3.にも注意されているとおり、属性値を直に参照するのは危ないので、お勧めできないということでしょう。

参考:「Why is document.getElementById not needed?

[追記: 2018年5月9日]「別要素のname属性に同名の値を与えてみる」の項とHTML 5.2仕様§6.3.3.邦訳を追加。

50
30
4

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
50
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?