【Javascript】 HTMLの要素を取得する
DOMはDocument Object Modelのことで、文書の構造をスクリプトから利用できるようにツリー状にしたものです。
というのは詳しく覚えていなくても普通に利用できるので、ここではDOMの基本的な操作を紹介します。
目次
操作をする前に
実は、Javascriptを実行する時点でHTMLの読み込みが完了しているとは限りません。HTMLの読み込みが完了する前にJavascriptでDOMを操作しようとしても、まだ読み込みが完了していなければ失敗してしまいます。そこで、読み込みが完了したというイベントを元に処理を開始します。
document.addEventListener("DOMContentLoaded", () => { // 処理 });
DOMContentLoaded
を用いたイベントは最初のHTML読み込みと解析が完了したときに実行されます。これで、読み込み後に実行されるようになりました。
DOMを操作するようなコードは、基本的にはDOMContentLoaded
のイベントの処理内容として書いていくことになります。(DOM構築後でないとDOM操作ができず、エラーとなるため)
もし画像やCSSなどの読み込みまで待ちたい場合、load
を使用します。
その他のイベントについては下の記事にあります。
開発にあたって注意点
基本的に, index.htmlをブラウザで開けばテストが可能ですが、HTMLやJavascriptを更新してチェックする際は、必ずページを更新しましょう。
反映されないなと思ったらCtrl + F5
で更新すると確実です。ローカルキャッシュを無視して再読込してくれます。
HTML準備
これまでの例のコードでは足りないので、少し増やします。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="app.js"></script> <title>Document</title> </head> <body> <header> <nav id="headerNav"> <ul> <li class="nav-item nav-top">トップ</li> <li class="nav-item">商品一覧</li> <li class="nav-item">カテゴリ</li> <li class="nav-item">タグ</li> </ul> </nav> </header> <main id="app"> <p>Hello, World!!</p> </main> <footer> <div class="copyright"> copyright ... </div> </footer> </body> </html>
このくらいあれば十分だと思います。
要素の取得
要素を取得する際の主な指定方法は、大まかに4種類あります。
- id属性で指定
- class属性で指定
- name属性で指定
- CSSのセレクタで指定
それぞれの書き方を見ていきましょう。
idで指定 (getElementById)
getElementById
を使えば、idを指定して取得できます。
const headerNav = document.getElementById("headerNav"); console.log(headerNav);
これで、idがheaderNav
である要素全体を取得できます。つまり、下のコード部分の要素です。
<nav id="headerNav"> <ul> 略 </ul> </nav>
CSSのセレクタで使った#
は不要です。
この取得結果を開発者ツールのconsoleで表示すると、次のような表示になります。

結果にマウスオーバーすると、対応する場所がハイライトされます。うまく要素を取得できている証拠です!
正確には、DOMのノードの場所を取得しています。
HTMLは階層化した構造で書かれており、木構造を用いることでその階層を処理します。木構造は、”ノード”とそれをつなぐ”エッジ”で構成されています。
classで指定 (getElementsByClassName)
class名を指定して取るには、getElementsByClassName
を利用します。
const navItems = document.getElementsByClassName("nav-item"); console.log(navItems);
結果は、配列で取得されます。
HTMLCollection(4) [li.nav-item.nav-top, li.nav-item, li.nav-item, li.nav-item] 0: li.nav-item.nav-top 1: li.nav-item 2: li.nav-item 3: li.nav-item
これらのそれぞれの項目は要素です。
const navItems = document.getElementsByClassName("nav-item"); for (let item of navItems) { console.log(item); }
<li class="nav-item nav-top">トップ</li> <li class="nav-item">商品一覧</li> <li class="nav-item">カテゴリ</li> <li class="nav-item">タグ</li>
nameで指定(getElementsByName)
上のHTML例にはありませんが、classと同様の方法で取得できます。主にフォームのinputを取得する際に用いることが多いと思います。
const email = document.getElementsByName("email");
セレクタで指定(querySelectorAll, querySelector)
CSSで使ったセレクタで指定もできます。querySelector
は最初の1つだけ、querySelectorAll
は全て取得します。
// 該当箇所全て取得 const navItems = document.querySelectorAll("#headerNav li"); console.log(navItems); // 該当箇所の最初の1個だけ取得 const navItems = document.querySelector("#headerNav li"); console.log(navItems);
NodeList(4) [li.nav-item.nav-top, li.nav-item, li.nav-item, li.nav-item] 0: li.nav-item.nav-top 1: li.nav-item 2: li.nav-item 3: li.nav-item <li class="nav-item nav-top">トップ</li>
親要素の取得
要素に対し、parentElement
を使います。
const ul = document.querySelector("#headerNav ul"); const parent = ul.parentElement; console.log(parent);
<nav id="headerNav"> <ul> <li class="nav-item nav-top">トップ</li> <li class="nav-item">商品一覧</li> <li class="nav-item">カテゴリ</li> <li class="nav-item">タグ</li> </ul> </nav>
ul
の親要素である<nav id="headerNav">...</nav>
が取れています。
子要素の取得
children
を使います。
const ul = document.querySelector("#headerNav ul"); const children = ul.children; console.log(children);
HTMLCollection(4) [li.nav-item.nav-top, li.nav-item, li.nav-item, li.nav-item] 0: li.nav-item.nav-top 1: li.nav-item 2: li.nav-item 3: li.nav-item
それぞれの子要素が配列に入ります。
取得した要素の中身を取得する
要素を取得するのには、何かしらの操作をしたいからだと思います。その中の文字列を取得して処理したり、内容を差し替えたりなどで活用します。ここではテキストの取得や置換を紹介します。
表示テキストのみ取得する(textContent)
textContent
を利用します。
const item = document.getElementsByClassName("nav-top")[0]; console.log(item.textContent);
トップ
テキスト部分だけ取得できました。次は中にHTMLタグが埋まっているパターンを見てみましょう。
const header = document.getElementById("headerNav"); console.log(header.textContent);
トップ 商品一覧 カテゴリ タグ
文字だけ取得できました! … が、やけにスペースが入っていますね。これは、HTMLのタグ周りだけ除去して、あとはHTMLの入力データをほぼそのまま取得しているためです。
textContent
はテキスト部分だけ抜き出してくれる便利なものですが、HTMLの構成の都合上余分なスペースが入ったり、改行がほしいところで入ってなかったり余分に入っていたりします。これを避けたい場合、文字列のスペースを除去するメソッドであるtrim
を使うと解決できます。
例えば、HTMLが
... <nav id="headerNav"> <ul> <li class="nav-item nav-top"> トップ</li> <li class="nav-item">商品一覧</li> ... </ul> </nav> ...
となっていたとすると、const item = document.getElementsByClassName("nav-top")[0];
の結果は
トップ
になります。これに対してtrim
を使うと、
const item = document.getElementsByClassName("nav-top")[0]; console.log( item.textContent.trim() );
トップ
という具合に、うまくスペースや改行を除去してくれます。しかし、これは文字列の最初と最後の連続したスペースや改行を除去するもので、文字列の途中にあるスペースは除去しないことに注意が必要です。
表示テキストを置換する
textContent
に代入します。
See the Pen DOM1 text replace1 by Totori (@souki202) on CodePen.
#app p
は<p>Hello, World!!</p>
を指定していますね。このコードは、textContentであるHello, World!!
をReplace!!
に置換するコードです。
このように、textContent
は表示テキストの取得だけでなく、代入するだけで置換が可能です。 (他の多くのメンバも同様です。)
ここで、#headerNav
のように中にHTMLを含んだものに対して置換を行うと、HTMLの中身は消えて設定したテキストだけが表示されます。
See the Pen DOM1 text replace2 by Totori (@souki202) on CodePen.
これは、#headerNav
の中身である
<ul> <li class="nav-item nav-top">トップ</li> <li class="nav-item">商品一覧</li> <li class="nav-item">カテゴリ</li> <li class="nav-item">タグ</li> </ul>
がまるごとReplace!!
に置き換わったというわけです。
また、textContent
による置換では、HTMLのタグを入れても全て普通に表示されます。
See the Pen DOM1 text replace3 by Totori (@souki202) on CodePen.
HTMLと認識させて置換したい場合、次のinnerHTML
を使うとうまくいきます。
HTMLごと取得する
innerHTML
を用います。
const header = document.getElementById("headerNav"); console.log(header.innerHTML);
<ul> <li class="nav-item nav-top">トップ</li> <li class="nav-item">商品一覧</li> <li class="nav-item">カテゴリ</li> <li class="nav-item">タグ</li> </ul>
HTMLが取得できました。取得するのは内側のHTMLで、指定した要素は含みません。
また、取得したHTMLはDOMではなくHTML文書そのもので、文字列です。少々扱いづらい機能と言えます。
この要素は、主に置換するときに役に立ちます。textContent
と同様に代入することで置換できますが、最も大きな違いは、HTMLを入れるとHTMLとして解釈してくれるという点です。
See the Pen DOM1 html replace by Totori (@souki202) on CodePen.
<h1>Replace!!</h1>
がHTMLとして解釈されているということがわかります。
まとめ
要素を取得するには、document.getElementById("id名")
などを用いると取得できます。取得した要素は、例えばtextContent
でテキストを取得したり、あるいは置換するといったことができます。
他にも様々な複雑な操作が可能です。次以降の章で見ていきましょう!
