今回、ちょっと躓いた部分があったので、個人的な備忘録としてまとめる。
タイトルにある通り、JavaScriptのgetElementsByNameに関することだ。
これらの基本的な使い方は既に知っている前提で話を進める。
これら自体の解説は調べればいくらでも出てくるので、分からない場合は各自で調べて欲しい。
躓いた内容
いきなりだが、以下のサンプルを見て欲しい。
<!DOCTYPE html>
<html labg="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
<script>
let t = document.getElementsByName("test");
console.log(t.length);
</script>
</head>
<body>
<p name="test">段落1</p>
<p name="test">段落2</p>
<p name="test">段落3</p>
</body>
</html>
HTMLでは、単純に3つの段落を書いている。
JavaScriptで、name
がtest
の要素を取得し、その要素数を出力する、ということをしている。
本来であれば3が出て欲しいところなのだが、これを実行すると0となってしまった。
…ある程度書いている方ならもうお分かりかと思うが、今回ちょっと躓いてしまったので自分向けにまとめておく。
要素数が0となった理由
これは、JavaScriptの実行タイミングが原因だ。
通常、ファイルの上から順番に処理が行われる。
今回、JavaScriptが書かれているのは、取得したい要素の前だ。
つまり、まだ処理されていない部分の内容を取得しようとしてしまっている。
そのため、中身を取得できずに要素数が0となってしまったのだ。
…要はケアレスミスである。
解決法
大まかな方針は、取得したい要素が処理されてからこのコードを実行すること。
ぱっと思いつく対策は二通り。
まず、JavaScriptの記述を下にずらしてしまう。
以下のような感じだ。
<!DOCTYPE html>
<html labg="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
</head>
<body>
<p name="test">段落1</p>
<p name="test">段落2</p>
<p name="test">段落3</p>
<script>
let t = document.getElementsByName("test");
console.log(t.length);
</script>
</body>
</html>
こうすれば、しっかり3と表示される。
もう一つは、画面の読み込みが終わってから実行させる記述にすること。
これには、以下のような書き方が用意されている。
window.onload = function(){
// 処理
}
こうすることで、画面の読み込みが終わった後に行う処理を書ける。
ここで、要素とその長さの取得を行えば問題ない、というわけだ。
これを使ったパターンは以下の通り。
<!DOCTYPE html>
<html labg="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
<script>
window.onload = function(){
let t = document.getElementsByName("test");
console.log(t.length);
}
</script>
</head>
<body>
<p name="test">段落1</p>
<p name="test">段落2</p>
<p name="test">段落3</p>
</body>
</html>
これでも、問題なく3と表示される。
今回躓いた原因
さて、これで一旦は解決なのだが、なぜこんな記事に残しておくほど躓いたかを書いておこう。
上では要素数の表示しか行っていなかったが、実際には要素自体の表示も行っていた。
サンプルとしては以下のような感じ。
<!DOCTYPE html>
<html labg="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
<script>
let t = document.getElementsByName("test");
console.log(t);
console.log(t.length);
</script>
</head>
<body>
<p name="test">段落1</p>
<p name="test">段落2</p>
<p name="test">段落3</p>
</body>
</html>
これを実行したところ、要素自体はしっかり表示されたのだ。
だから、その時点で要素が取得できていたと勘違いをしていた。
…が、ここで一個疑問が。
なぜ、要素自体の表示はできていたのかが謎なのだ。
現状、getElementsByNameで返されるNodeListが生きたコレクションであることが絡んでいるのではないか、とにらんでいる。
ドキュメントに、以下のような記載があるのだ。
elements は、生きた
Document.getElementsByName() – Web API | MDNNodeList
コレクション、つまり文書内で同じname
を持った新しい要素が追加されたり削除されたりすると自動的に更新されるものです。
これで、後で読み込まれたものが更新され表示されているのか、ということだ。
ただ、それでも二つの疑問が残る。
- やはり表示のタイミングでは対象が読み込まれていないはずなので、何も表示されないのでは?
- そこが後で更新されるとしたら、要素数の表示が更新されないのはなぜか?
今のところ、ここが最前線だ。
もし今後調べて何かわかったら、ここに追記するとしよう。
コメント