LoginSignup
5
2

More than 1 year has passed since last update.

【JavaScript】DOMについて

Posted at

はじめに

JavaScriptの基礎を勉強したらとても良い学びになったのでメモ第3弾です
JavaScriptのDOMについてです

ちなみに2回目はこちら↓

こちらの本を参考にさせていただきました

概要

DOMとは:

Document Object Model
マークアップ言語を操作する標準の仕組み

DOMはドキュメントを文書ツリーとして扱う
文書に含まれる要素や属性、テキストをそれぞれオブジェクト(=ノード)と見なし、「オブジェクトの集合が文書である」と考える

DOMはこれらノードを抽出/追加/置換/削除するための汎用的な手段を提供するAPI

dom.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>【JavaScript】DOMについて</title>
</head>
<body>
  <p id="greet">これが<strong>文書ツリー</strong>です</p>
</body>
</html>

上記HTMLコードはこう解釈される↓

DOM.png

クライアントサイドJavaScriptの前提知識

JavaScriptでクライアントサイド開発を進めるうえで欠かせない知識は以下の3つ

  1. 要素ノードの取得
  2. 文書ツリー間の行き来
  3. イベントドリブンモデル

1. 要素ノードを取得する

文書ツリーから操作対象となる要素ノードを取り出す必要がある

要素ノードを取得する主な方法は以下の3つ

  • document.getElementById()
  • document.querySelector()
  • document.querySelectorAll()

document.getElementById()

指定されたid値を持つ要素をElementオブジェクトとして返す
存在しない場合、nullが返る

HTML
<span id="spanText">Hello</span>
JavaScript
var spanText = document.getElementById('spanText');
console.log(spanText); //<span>
console.log(spanText.textContent); // "Hello"

// 要素を取得できていない例
var divText = document.getElementById('divText');
console.log(divText); // null

取得した要素(Elementオブジェクト)に対してテキストを埋め込むにはtextContentというプロパティを利用する

document.querySelector()/document.querySelectorAll()

CSSセレクタでマッチした要素を取得する

CSSセレクタとは
CSSによるデザイン指定をどのHTML要素に適用させるかを指定するもの

getXxxxxメソッドが特定の名前/属性値をキーに要素を検索していたのに対して、より複雑な条件での検索が可能

HTML
<ul id="list">
  <li><p class="en">Hello</p></li>
  <li><p class="en">GoodBye</p></li>
  <li><p class="ja">こんにちは</p></li>
  <li><p class="ja">さようなら</p></li>
</ul>
JavaScript
const foo01 = document.querySelector('#list .en');
console.log(foo01.textContent);
// Hello

const foo02 = document.querySelectorAll('#list .en');
for(let i=0,len=foo02.length; i<len; i++){
  console.log(foo02.item(i).textContent);
  //Hello
  //GoodBye
}

querySelector()は一番最初にマッチした要素のみ取得する
戻り値はElementオブジェクト(単一)

querySelectorAll()はマッチした要素全てを取得する
戻り値はNodeListオブジェクト

取得したNodeListの使い方(一例)

配列に変換する

JavaScript
var elem =[].slice.call(document.querySelectorAll('#list'));

slice()
配列を新しい配列オブジェクトに作成して返すメソッド

call()
他のオブジェクトが持つメソッドを自分のメソッドのように呼び出すメソッド

getXxxxxメソッドとqueryXxxxxメソッドの使い分け

  • getXxxxxメソッド(高速、低機能):特定のid値、class属性などで要素を検索できる場合
  • queryXxxxxメソッド(低速、高機能):より複雑な条件で検索したい場合

2. 文書ツリー間の行き来

あるノードを起点として相対的な位置関係からノードを取得する(=ノードウォーキング)

1.のgetXxxxx/queryXxxxxメソッドは特定の要素ノードを取得するためのメソッド

以下の例は、要素の配下に含まれる要素を取り出し、そのvalue属性の値を列挙する

HTML
<form>
  <label for="country">一番好きな国は?:</label>
  <select id="country">
    <option value="アメリカ">アメリカ</option>
    <option value="日本">日本</option>
    <option value="中国">中国</option>
  </select>
<input type="submit" value="送信" />
</form>
JavaScript
const s = document.getElementById('country');

// <select>要素配下の子ノードを取得
const opts = s.childNodes;

// 子ノードを順に取得
for(let i = 0, len = opts.length; i < len; i++){
  let opt = opts.item(i);
 // 子ノードが要素ノードである場合にのみ、その値をログ表示
  if(opt.nodeType === 1) {
    console.log(opt.value);
    // "アメリカ" "日本" "中国"
  }
}

childNodesプロパティは要素直下の子ノード群を取得し、NodeListオブジェクトとして返す。

しかし、リストに含まれるノードは要素だけではないため、今回のように要素だけを取り出したい場合は、取り出したノードが要素ノードであるかを確認する必要がある。

タグの間にある改行や空白はテキストノードと見なされる

nodeTypeプロパティを用いてノードの種類を判定する
以下は、nodeTypeプロパティの対応表(抜粋)

戻り値 概要
1 要素ノード
2 属性ノード
3 テキストノード
4 CDATAセクション
5 実態参照ノード
6 実態宣言ノード
7 処理命令ノード

今回の例では、nodeTypeプロパティが1(要素ノード)である場合にのみ、その値(valueプロパティ)を取得

イベントドリブンモデル

イベントドリブンモデル:
ブラウザ上で発生するイベントに応じて、実行するコードを記述するプログラミングのモデル

イベントドリブンモデル=イベント+イベントハンドラー(/ イベントリスナー)

イベント

ページ内で発生した様々な出来事

JavaScriptで利用できる主なイベント(抜粋)

分類 イベント名 発生タイミング 主な対象要素
読み込み load 画像の読み込みが完了したとき body,img
マウス click クリック時 -
マウス mouseover マウスポインターが要素に乗った時 -
キー keydown キーを押したとき -
フォーム submit サブミットボタンを押した時 form
フォーカス focus 要素がフォーカスされた時 -
その他 scroll スクロールした時 body

イベントハンドラー(/ イベントリスナー)

イベントに対応してその処理内容を定義するコードのかたまり(関数)

イベントハンドラー(/ イベントリスナー)を定義する

定義方法は以下の3種類

  1. addEventListenerメソッドを使って宣言する(イベントリスナー)
  2. タグ内の属性として宣言する(イベントハンドラー)
  3. 要素オブジェクトのプロパティとして宣言する(イベントハンドラー)

基本的には、DOM Level2で定義され、標準化されている(1.の)addEventListenerメソッドを利用する

1. addEventListenerメソッドを使って宣言する

2.と3.のイベントハンドラーと違うのは、同一要素/同一イベントに対して複数のイベントハンドラー(のようなもの)を紐づけられる点

以下はボタンクリックでウィンドウアラートが出る例

HTML
<input id="btn" type="button" value="ダイアログ表示"> 
JavaScript
// ページがロードされたタイミングでイベントを登録
document.addEventListener('DOMContentLoaded', function(){
    document.getElementById('btn').addEventListener('click', function() {
  window.alert('ボタンがクリックされました');
  },false);
},false);

image.png

DOMContentLoadedイベントリスナー:
コンテンツ本体がロードされたところで実行
onloadイベントハンドラ:
コンテンツ本体とすべての画像がロードされたところで実行

2. タグ内の属性として宣言する

最もシンプルな記法

HTML
<input type="button" value="ダイアログ表示" onclick="btn_click()" />
JavaScript
function btn_click() {
  window.alert('ボタンがクリックされました');
}

HTMLに直接記述することもできる(可読性の観点から△)

HTML
<input type="button" value="ダイアログ表示" onclick="window.alert('ボタンがクリックされました')" />

3. 要素オブジェクトのプロパティとして宣言する

関連付けとイベントハンドラーそのものの宣言とをまとめてJavaScriptのコード内で記述する

HTML
<input id="btn" type="button" value="ダイアログ表示" />
JavaScript
// ページロード時に実行されるイベントハンドラーを登録
window.onload = function() {
  // ボタンクリック時に実行されるイベントハンドラーを登録
  document.getElementById('btn').onclick = function() {
    window.alert('ボタンがクリックされました');
  };
}

さいごに

JavaScriptでの基本的なDOMについて勉強し、まとめてみました

仕事でちょうどDOMを扱ったのでよい復習になりました

このほかにも、参考にさせていただいた書籍では深堀りし解説しているので、気になった方はチェックしてみてください

参考

5
2
0

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
5
2