LoginSignup
30
28

More than 3 years have passed since last update.

JavaScriptによるDOM操作

Last updated at Posted at 2019-12-29

インターフェース(単数ノード)

継承
 Node
  └ Element
  │  └ HTMLElement
  │     ├ HTMLAnchorElement
  │     ├ HTMLAreaElement
  │     ├ HTMLAudioElement
  │     ├ ....
  │
  ├ Text
  ├ Comment

Node

DOMを構成する文字列、コメント、タグなどを扱うためのインターフェースです。

<!DOCTYPE html>
<!-- cmment -->
<p>Text</p> (p要素も、その中のテキストも別のノード)

Element

Nodeを継承しています。

<xml>
<svg>

HTMLElement

Elementを継承しています。

<header>
<main>
<footer>
<article>
<section>
<aside>
<nav>

HTML(*)Element

HTMLElementを継承しています。

HTMLタグ インターフェース
<a> HTMLAnchorElement
<area> HTMLAreaElement
<audio> HTMLAudioElement
<br> HTMLBRElement
<base> HTMLBaseElement
<blockquote><q> HTMLQuoteElement
<body> HTMLBodyElement
<button> HTMLButtonElement
<canvas> HTMLCanvasElement
<dl> HTMLDListElement
<data> HTMLDataElement
<datalist> HTMLDataListElement
<details> HTMLDetailsElement
<div> HTMLDivElement
<embed> HTMLEmbedElement
<fieldset> HTMLFieldSetElement
<form> HTMLFormElement
<h1><h6> HTMLHeadingElement
<head> HTMLHeadElement
<hr> HTMLHRElement
<html> HTMLHtmlElement
<iframe> HTMLIFrameElement
<img> HTMLImageElement
<input> HTMLInputElement
<label> HTMLLabelElement
<legend> HTMLLegendElement
<li> HTMLLIElement
<link> HTMLLinkElement
<map> HTMLMapElement
<media> HTMLMediaElement
<meta> HTMLMetaElement
<meter> HTMLMeterElement
<del><ins> HTMLModElement
<ol> HTMLOListElement
<object> HTMLObjectElement
<optgroup> HTMLOptGroupElement
<option> HTMLOptionElement
<output> HTMLOutputElement
<p> HTMLParagraphElement
<param> HTMLParamElement
<pre> HTMLPreElement
<progress> HTMLProgressElement
<script> HTMLScriptElement
<select> HTMLSelectElement
<slot> HTMLSlotElement
<source> HTMLSourceElement
<span> HTMLSpanElement
<style> HTMLStyleElement
<caption> HTMLTableCaptionElement
<th><td> HTMLTableCellElement
<col><colgroup> HTMLTableColElement
<table> HTMLTableElement
<tr> HTMLTableRowElement
<thead><tbody><tfoot> HTMLTableSectionElement
<template> HTMLTemplateElement
<textarea> HTMLTextAreaElement
<time> HTMLTimeElement
<title> HTMLTitleElement
<track> HTMLTrackElement
<ul> HTMLUListElement
<video> HTMLVideoElement

<audio><video>はHTMLMediaElementも継承しています。

Text

Node を継承しています。

Comment

Node を継承しています。

ノードの種類の判定

js
console.log(sampleNode.nodeType);
ノードの種類 nodeTypeの返り値
ELEMENT_NODE 1
TEXT_NODE 3
PROCESSING_INSTRUCTION_NODE 7
COMMENT_NODE 8
DOCUMENT_NODE 9
DOCUMENT_TYPE_NODE 10
DOCUMENT_FRAGMENT_NODE 11

インターフェース(複数ノード)

HTMLCollectionとNodeListの共通点

配列風インターフェースです。
動的(取得後にDOMに変更があった場合はリアルタイムで中身が変わる)※querySelectorAll()を除く

HTMLCollectionとNodeListの違い

インターフェース 違い
HTMLCollection 要素ノード以外のノードを含まない
NodeList 要素ノード以外のノードを含んでいる可能性がある

HTMLCollectionを取得するメソッド

getElementsByTagName

document.getElementsByTagName()
element.getElementsByTagName()
タグ名を指定して取得します。

html
<div>a</div>
<div>b</div>
<div>c</div>
js
const sampleDivs = document.getElementsByTagName("div");
console.log(sampleDivs);

getElementsByClassName

document.getElementsByClassName()
element.getElementsByClassName()
クラス名を指定して取得します。

html
<div class="box">a</div>
<div class="box">b</div>
<div class="box">c</div>
js
const boxes = document.getElementsByClassName("box");
console.log(boxes); //HTMLCollection(3) [div.box, div.box, div.box]

HTMLCollectionを取得するプロパティ

HTMLCollectionを返すプロパティ 内容
document.forms ドキュメント内のform要素ノードを全て格納したもの
document.images ドキュメント内のimg要素ノードを全て格納したもの
document.links ドキュメント内のa、area要素ノードを全て格納したもの
node.children 指定したノードの子要素ノード全て格納したもの

HTML(*)Collection

HTMLCollectionを継承した独自のインターフェースです。

HTML(*)Collection 内容
HTMLFormControlsCollection 要素内のフォーム系要素
HTMLOptionsCollection option要素のコレクション

NodeListを取得するメソッド

getElementsByName

document.getElementsByName()
name属性の値で取得します。
※IE,EdgeはHTMLCollectionを返します。

html
<div name="box">a</div>
<div name="box">b</div>
<div name="box">c</div>
js
const boxes = document.getElementsByName("box");
console.log(boxes);

querySelectorAll()

document.querySelectorAll()
element.querySelectorAll()
CSSセレクタでマッチした要素全てを取得します。

html
<div class="box">a</div>
<div class="box">b</div>
<div class="box">c</div>
js
const box = document.querySelectorAll(".box");
console.log(box); //NodeList(3) [div.box, div.box, div.box]
静的なNodeList

querySelectorAll()で取得した場合、静的なNodeListになります。
取得後にDOMに変更があった場合も中身が変わりません。
その時点でのノードを静的リストに集めるので、取得時にパフォーマンスの低下を引き起こします。

NodeListを取得するプロパティ

NodeListを返すプロパティ 内容
node.childNodes 指定したノードの子ノード全て格納したもの

NodeListとHTMLCollectionの使い方

NodeList、HTMLCollectionはそのままでは要素を扱えません。

for文を使う

HTMLCollection
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divCollection = document.getElementsByTagName("div");
console.log(divCollection); //HTMLCollection

for (let i = divCollection.length; i--;) {
  console.log(divCollection[i]); //各div
}
NodeList
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divList = document.querySelectorAll("div");
console.log(divList); //NodeList

for (let i = divList.length; i--;) {
  console.log(divList[i]); //各div
}

for ...ofを使う

HTMLCollection
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divCollection = document.getElementsByTagName("div");
console.log(divCollection); //HTMLCollection

for (const div of divCollection) {
  console.log(div); //各div
}
NodeList
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divList = document.querySelectorAll("div");
console.log(divList); //NodeList

for (const div of divList) {
  console.log(div);
}

forEachを使う

HTMLCollection

HTMLCollectionはforEachが使えません。

NodeList
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divList = document.querySelectorAll("div");
console.log(divList); //NodeList

divList.forEach((div) => {
  console.log(div); //各div
})

配列に変換する

JavaScriptの配列 記事書きました。

HTMLCollection
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divCollection = document.getElementsByTagName("div");
console.log(divCollection); //HTMLCollection 

//配列化
const divArray = [...divCollection];

//配列か判定
console.log(Array.isArray(divArray)); //true
NodeList
html
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
js
const divList = document.querySelectorAll("div");
console.log(divList); //NodeList

//配列化
const divArray = [...divList];

//配列か判定
console.log(Array.isArray(divArray)); //true

HTMLCollection、NodeListからノードを取り出す

html
<div class="box" id="sampleDiv1">1</div>
<div class="box" id="sampleDiv2">2</div>
<div class="box" id="sampleDiv3">3</div>
<div class="box" id="sampleDiv4">4</div>
js
const sampleHTMLCollection = document.getElementsByClassName("box");
const sampleNodeList = document.querySelectorAll("box");

//HTMLCollectionを取得
console.log(sampleHTMLCollection);

//NodeListを取得
console.log(sampleNodeList); 

//HTMLCollectionの長さを取得
console.log(sampleHTMLCollection.length); 

//NodeListの長さを取得
console.log(sampleNodeList.length); 

//0番目の要素ノードを取得
console.log(sampleHTMLCollection[0]); 

//0番目のノードを取得
console.log(sampleNodeList[0]); 

インターフェースの判定

例:divならNode、Element、HTMLElement、HTMLDivElementの4つがtrueになります。

js
console.log(sampleNode instanceof Node);
console.log(sampleNode instanceof Element);
console.log(sampleNode instanceof HTMLElement);
console.log(sampleNode instanceof HTMLDivElement);//divの場合(他の要素ノードの場合はHTML(*)Elementの表参照)
console.log(sampleNode instanceof Text);
console.log(sampleNode instanceof Comment);
console.log(sampleNodes instanceof HTMLCollection);
console.log(sampleNodes instanceof NodeList);

取得

親要素への参照を取得済みの場合はdocument全体を指定する代わりに要素の子だけを指定可能です。
(対象を絞ってセレクターをシンプルにしてパフォーマンスを向上)

HTMLElementを取得するメソッド

getElementById

document.getElementById()
element.getElementById()はありません。
IDを指定して要素を取得します。
もし存在しなかった場合は null を返します。
※同じIDを持つ要素が複数存在する場合は最初の要素のみ取得

html
<div class="first">a</div>
<div class="second">b</div>
<div class="third">c</div>
js
const secondBox = document.getElementById("second");
console.log(secondBox);

querySelector()

document.querySelector()
element.querySelector()
CSSセレクタでマッチした最初の要素を取得します。

html
<div class="box">a</div>
<div class="box">b</div>
<div class="box">c</div>
js
const box = document.querySelector(".box");
console.log(box);//<div class="box">a</div>

html要素、head要素、body要素の取得

js
const html = document.documentElement;
console.log(html);

const head = document.head;
console.log(head);

const body = document.body;
console.log(body);

要素がCSSセレクタと一致しているか確認

html
<div id="parent">
  <p id="child" class="great">
    サンプルテキスト
  </p>
</div>
js
//調べたいノードを取得
const child = document.getElementById("child");

//CSSセレクタと一致しているか確認
console.log(child.matches("div#parent p.great")); //true

祖先

取得

CSSセレクタで祖先を取得します。
(自分自身も取得できます。)

html
<div id="ancestor">
  <div id="parent">
    <div id="child">
      <div id="grandchild">
      </div>
    </div>
  </div>
</div>
js
//基準となる#childを取得
const childElement = document.getElementById("child");

//祖先の取得
console.log(childElement.closest("#ancestor")); //取得可能

//親の取得
console.log(childElement.closest("#parent")); //取得可能

//自身の取得
console.log(childElement.closest("#child")); //取得可能

//子の取得
console.log(childElement.closest("#grandchild"));//null

取得

ノード全種 要素ノードのみ
親ノードを取得 parentNode parentElement
parentNodeとparentElementの違い
プロパティ html要素の親取得時
parentNode Documentを返す
parentElement nullを返す
html
<div id="parent">
  <div id="child"></div>
</div>
js
//基準となる子要素の取得
const child = document.getElementById("child");

//子要素の親の取得
const parent = child.parentElement;
//const parent = child.parentNode;

//指定した要素ノードの親を取得
console.log(parent);
子ノードを持つか判定
html
<div id="parent">
  <div id="child"></div>
</div>
js
//基準となる親要素の取得
const parent = document.getElementById("parent");

//指定の要素ノードが子ノードを持つか判定
console.log(parent.hasChildNodes()); //true

プロパティ ノード全種 要素ノードのみ
最初のノードを取得 firstChild firstElementChild
親ノードを取得 parentNode parentElementNode
子ノード(複数) childNodes children
最初の子ノード firstChild firstElementChild
最後の子ノード lastChild lastElementChild

element.childrenとNode.childNodesの違い

プロパティ 内容
element.children HTMLCollectionになる
Node.childNodes NodeList になる

子要素の取得

html
<div id="parent">
  <div id="child1"></div>
  <div id="child2"></div>
  <div id="child3"></div>

  <div id="childx"></div>
</div>
js
//基準となる親要素の取得
const parent = document.getElementById("parent");

//最初の子の取得
const child1 = parent.firstElementChild;
console.log(child1);

//最後の子の取得
const childx = parent.lastElementChild;
console.log(childx);

兄弟

内容 ノード全種 要素ノードのみ
前のノード previousSibling previousElementSibling
次のノード nextSibling nextElementSibling
html
<div class="box" id="box1">1</div>
<div class="box" id="box2">2</div>
<div class="box" id="box3">3</div>
js
const box2 = document.getElementById("box2");

console.log(box2.previousElementSibling);
console.log(box2.nextElementSibling);

要素ノードの作成

js
//要素ノードの作成
const sampleElement = document.createElement("div");
sampleElement.textContent = "サンプルテキスト";

//ドキュメント内に配置
document.body.appendChild(sampleElement);

要素ノードの追加

長子の追加

html
<div id="parent">
  <div id="child"></div>
</div>
js
//基準となる親ノードの取得
const parent = document.getElementById("parent");

//追加する要素ノードの作成
const newChild = document.createElement("div");
newChild.setAttribute("id", "newChild");

//最初の子として追加
parent.prepend(newChild);

末子の追加

html
<div id="parent">
  <div id="child"></div>
</div>
js
//基準となる親ノードの取得
const parent = document.getElementById("parent");

//追加する要素ノードの作成
const newChild = document.createElement("div");
newChild.setAttribute("id", "newChild");

//最後の子として追加
parent.appendChild(newChild);

appendChild()に似たメソッドとしてappend()があります。

append() appendChild()
対象 DOMStringも追加可能 Node オブジェクトのみ
戻り値 なし 追加されたNode オブジェクトを返す
複数のノードや文字列を追加可能 一つのノードだけ

指定の子要素の前に追加

html
<div id="parent">
  <div id="child_1"></div>
  <div id="child_2"></div>
</div>
js
//基準となる親ノードの取得
const parent = document.getElementById("parent");

//基準となる二番目の子の取得
const child2 = document.getElementById("child_2");

//追加する要素ノードの作成
const newChild = document.createElement("div");
newChild.setAttribute("id", "newChild");

//二番目の子の前に追加
parent.insertBefore(newChild, child2);

指定要素の前に追加

html
<div id="parent">
  <div id="child_1"></div>
  <div id="child_2"></div>
</div>
js
//基準となる二番目の子の取得
const child2 = document.getElementById("child_2");

//追加する要素ノードの作成
const newChild = document.createElement("div");
newChild.setAttribute("id", "newChild");

//二番目の子の前に追加
child_2.before(newChild);

指定要素の後に追加

html
<div id="parent">
  <div id="child_1"></div>
  <div id="child_2"></div>
</div>
js
//基準となる1番目の子の取得
const child1 = document.getElementById("child_1");

//追加する要素ノードの作成
const newChild = document.createElement("div");
newChild.setAttribute("id", "newChild");

//1番目の子の後に追加
child_1.after(newChild);

HTML要素の追加

引数 挿入位置
beforebegin 親要素の直前
afterbegin 親要素内の先頭
beforeend 親要素の末尾
afterend 親要素の直後
html
<div id="parent">
  <div id="child1"></div>
  <div id="child2"></div>
</div>
js
//基準となる親を取得
const parent = document.getElementById("parent");

//div要素を作成して親の前に追加
const newDiv = document.createElement('div');
parent.insertAdjacentElement("beforebegin", newDiv);

//p要素を作成して親の後に追加
const newP = document.createElement('p');
parent.insertAdjacentElement("afterend", newP);

//span要素を作成して最初の子として追加
const newSpan = document.createElement('span');
parent.insertAdjacentElement("afterbegin", newSpan);

//strong要素を作成して最後の子として追加
const newStrong = document.createElement('strong');
parent.insertAdjacentElement("beforeend", newStrong);

文字列をHTMLとして追加

引数 挿入位置
beforebegin 親要素の直前
afterbegin 親要素内の先頭
beforeend 親要素の末尾
afterend 親要素の直後
html
<div id="parent">
  <div id="child1"></div>
  <div id="child2"></div>
</div>
js
//基準となる親を取得
const parent = document.getElementById("parent");

//div要素を作成して親の前に追加
const inserBeforeParent = "<div>parentの前</div>"
parent.insertAdjacentHTML("beforebegin", inserBeforeParent);

//div要素を作成して親の後に追加
const inserAfterParent = "<div>parentの後</div>"
parent.insertAdjacentHTML("afterend", inserAfterParent);

//div要素を作成して最初の子として追加
const inserBeforeFirstChild = "<div>parentの最初の子の前</div>"
parent.insertAdjacentHTML("afterbegin", inserBeforeFirstChild);

//div要素を作成して最後の子として追加
const inserAfterLastChild = "<div>parentの最後の子の後</div>"
parent.insertAdjacentHTML("beforeend", inserAfterLastChild);

削除

ノードの削除

html
<div id="parent">
  <div id="child1"></div>
  <div id="child2"></div>
</div>
js
const child1 = document.getElementById("child1");
child1.remove();

子ノードの削除

html
<div id="parent">
  <div id="child1"></div>
  <div id="child2"></div>
</div>
js
const parent = document.getElementById("parent");

const child1 = document.getElementById("child1");

parent.removeChild(child1);

置換

ノードの置換

html
<div id="parent">
  <div id="child"></div>
</div>
js
//置換対象の要素ノードを取得
const child = document.getElementById("child");

//新しい要素ノードを作成
const newChild = document.createElement("div");
newChild.classList.add("newChild");

//置換
child.replaceWith(newChild);

子ノードの置換

html
<div id="parent">
  <div id="child"></div>
</div>
js
const parent = document.getElementById("parent");

const child = document.getElementById("child");

const newChild = document.createElement("newChild");
newChild.classList.add("newChild");

parent.replaceChild(newChild, child);

複製

ノードの複製

cloneNodeの引数 内容
true 子ノードを含めて複製
false 子ノードを含めず複製
html
 <div id="box"></div>
js
//複製元の要素の取得
const box = document.getElementById("box");

//複製
const clonedBox = box.cloneNode(true);

//配置
document.body.appendChild(clonedBox);

テーブル

table

table用の情報の取得

プロパティ 内容
caption table要素のcaption要素を返す
tHead table要素のthead要素を返す
tBodies table要素のthead要素を返す(bodyは複数ある可能性があるのでHTMLCollectionで返る)
tBodies.length tBodiesの数を返す
tFoot table要素のtfoot要素を返す
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th>ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTable = document.getElementById("sampleTable");

console.log(sampleTable.caption); //table要素のcaptionを取得
console.log(sampleTable.tHead); //table要素のtHeadを取得
console.log(sampleTable.tBodies); //table要素のtBodiesを取得
console.log(sampleTable.tBodies.length); //table要素のtBodiesの数を取得
console.log(sampleTable.tFoot); //table要素のtFootを取得

作成

メソッド 内容
createCaption() captionを作成(captionが存在した場合は既存のtheadを返す)
createTHead() theadを作成(theadが存在した場合は既存のtheadを返す)
createTBody() tbodyを作成
createTFoot() tfootを作成(tfootが存在した場合は既存のtfootを返す)
html
<table id="sampleTable">
</table>
js
const sampleTable = document.getElementById("sampleTable");

sampleTable.createCaption(); //table要素にcaptionを作成
sampleTable.createTHead(); //table要素にtHeadを作成
sampleTable.createTBody(); //table要素にtBodyを作成
sampleTable.createTFoot(); //table要素にtFootを作成

削除

メソッド 内容
deleteCaption() captionが無い場合は何も起きない(エラーにもならない)
deleteTHead() theadが無い場合は何も起きない(エラーにもならない)
deleteTBody() tbodyが無い場合は何も起きない(エラーにもならない)
deleteTFoot() tfootが無い場合は何も起きない(エラーにもならない)
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th>ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTable = document.getElementById("sampleTable");

sampleTable.deleteCaption(); //table要素のcaptionを削除
sampleTable.deleteTHead(); //table要素のtHeadを削除
sampleTable.deleteTFoot(); //table要素のtFootを削除

列・セル

列・セルの取得

プロパティ 要素 内容
rows table要素のプロパティ そのテーブルが持つtr要素をHTMLCelloctionで返す
cells tr要素のプロパティ その列が持つセルをHTMLCelloctionで返す
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th>ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTable = document.getElementById("sampleTable");
console.log(sampleTable.rows);

const sampleTr1 = document.getElementById("sampleTr1");
console.log(sampleTr1.cells);

列・セルの追加

メソッド 要素 内容
insertRow() table要素のメソッド 指定した番目の列の追加
insertCell() tr要素のメソッド 指定した番目のセルの追加
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th>ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTable = document.getElementById("sampleTable");
sampleTable.insertRow(3); //テーブル内に4番目のtrが追加される

const sampleTr1 = document.getElementById("sampleTr1");
sampleTr1.insertCell(0); //sampleTr1の最初の子としてtdが追加される

列・セルの削除

メソッド 要素 内容
deleteRow() table要素のメソッド 指定した番目の列の削除
deleteCell() tr要素のメソッド 指定した番目のセルの削除
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th>ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTable = document.getElementById("sampleTable");
sampleTable.deleteRow(1); //テーブル内の2番目のtrが削除される

const sampleTr1 = document.getElementById("sampleTr1");
sampleTr1.deleteCell(0); //sampleTr1の最初のセルが削除される

列・セルの位置

プロパティ 要素 内容
rowIndex tr要素のプロパティ テーブル要素の中でそのtrが何番目か
cellIndex th要素、td要素のプロパティ 列の中でそのセルが何番目か
html
<table id="sampleTable">

  <caption>キャプション</caption>

  <thead>
    <tr id="sampleTr1">
      <th id="sampleTh1">ヘッダーセル1</th>
      <th>ヘッダーセル2</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>データセル1</td>
      <td>データセル2</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>フッターセル1</td>
      <td>フッターセル2</td>
    </tr>
  </tfoot>

</table>
js
const sampleTr1 = document.getElementById("sampleTr1");
console.log(sampleTr1.rowIndex); //table内の何番目のtrかを取得

const sampleTd1 = document.getElementById("sampleTd1");
console.log(sampleTd1.cellIndex); //tr内の何番目のセルかを取得

テキストノード

テキストノードの作成

js
テキストノードの作成
const sampleText = document.createTextNode("サンプルテキスト");

//ドキュメント内に配置
document.body.appendChild(sampleText);

テキストノードの取得

textContentによる取得

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

console.log(box.textContent); //boxの子ノードのテキストノード3つのテキストを併せたものを取得

nodeValueによる取得

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

console.log(box.firstChild.nodeValue); //box直下のテキストノードのみ取得

テキストノードの置換

HTMLを書いてもタグは文字列として出力されます。

textContentによる置換

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

box.textContent = "書き換えたテキスト";//boxの子ノードがテキストノード「書き換えたテキスト」だけになる

nodeValueによる置換

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

box.firstChild.nodeValue = "書き換えたテキスト";//box直下のテキストノードだけが「書き換えたテキスト」になる

テキストノードの削除

textContentによる削除

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

box.textContent = ""; //boxの子ノード全てが削除される

nodeValueによる削除

html
<div id="box">サンプルテキスト
  <span>サンプルテキスト</span>
  <span>サンプルテキスト</span>
</div>
js
const box = document.getElementById("box");

box.firstChild.nodeValue = ""; //box直下のテキストノードだけが削除される

コメントノード

コメントノードの作成

js
コメントノードの作成
const myComment = document.createComment('サンプルテキスト');

//ドキュメント内に配置
document.body.appendChild(myComment);

属性ノード

属性ノードは、要素ノードの中にありますが、子ノードではありません。

テキストノードと属性ノードの違い 関係性
要素ノードとテキストノード 親と子供
要素ノードと属性ノード 親とアクセサリー

属性ノードの取得

html
<a href="https://www.google.co.jp" target="_blank" id="anchor">サンプルテキスト</a>
js
const sampleAnchor = document.getElementById("anchor");

console.log(sampleAnchor.getAttribute("target")); //_blank

特定の属性を持つ要素の取得

html
<a href="test1.html">サンプルテキスト1</a>
<a href="https://www.google.co.jp" target="_blank">サンプルテキスト2</a>
<a href="test2.html">サンプルテキスト3</a>
js
const sampleAnchor = document.querySelector("[target]");
console.log(sampleAnchor);

特定の属性が特定の値を持つ要素を取得する

html
<a href="https://www.google.co.jp" target="_blank">サンプルテキスト1</a>
<a href="https://www.google.co.jp" target="_self">サンプルテキスト2</a>
<a href="https://www.google.co.jp" target="_top">サンプルテキスト3</a>
<a href="https://www.google.co.jp" target="_parent">サンプルテキスト4</a>
js
const sampleAnchor = document.querySelector('[target="_top"]');
console.log(sampleAnchor);

属性ノードの置換

html
<a href="https://www.google.co.jp" target="_blank" id="anchor">サンプルテキスト</a>
js
const sampleAnchor = document.getElementById("anchor");

sampleAnchor.setAttribute("target", "_self");

属性ノードの削除

html
<a href="https://www.google.co.jp" target="_blank" id="anchor">サンプルテキスト</a>
js
const sampleAnchor = document.getElementById("anchor");

sampleAnchor.removeAttribute("target");

属性ノードの属性の作成、追加

作成はdocumentオブジェクトに対して行います。

html
<a href="https://www.google.co.jp" id="anchor">サンプルテキスト</a>
js
//属性を追加する要素を取得
const sampleAnchor = document.getElementById("anchor");

//属性の作成
const sampleAttribute = document.createAttribute("target");

//属性に値を与える
sampleAttribute.value = "_blank";

//要素に属性を追加する
sampleAnchor.setAttributeNode(sampleAttribute);

属性ノードの有無の判定

html
<a href="https://www.google.co.jp" target="_blank" id="anchor">サンプルテキスト</a>
js
const sampleAnchor = document.getElementById("anchor");

console.log(sampleAnchor.hasAttribute("target")); //true

カスタムデータ属性

data-*="値"の形
属性ノードなのでgetAttribute()、setAttribute()、hasAttribute()、removeAttribute()も使用できます。

例として、data-testとして追加します。

カスタムデータ属性の追加、更新

html
<div id="box"></div>
js
const box = document.getElementById("box");

box.dataset.test = "myValue";

特定のカスタムデータ属性を持つ要素の取得

data属性の存在自体の有無で絞り込み

html
<div data-test="box">1</div>
<div>2</div>
<div data-test="box">3</div>
js
const boxes = document.querySelectorAll("[data-test]");
console.log(boxes);

特定の カスタムデータ属性が特定の値を持つ要素を取得する

html
<div data-test="box1">1</div>
<div data-test="box2">2</div>
<div data-test="box3">3</div>
js
const boxes = document.querySelectorAll('[data-test="box2"]');
console.log(boxes);

クラス

クラスの追加

html
<div id="box"></div>
js
const box = document.getElementById("box");

box.classList.add("great");

クラスの削除

html
<div id="box" class="great"></div>
js
const box = document.getElementById("box");

box.classList.remove("great");

クラスの有無の判定

html
 <div id="box" class="great"></div>
js
const box = document.getElementById("box");

console.log(box.classList.contains("great")); //true

クラスの有無のスイッチング

html
<div id="box1" class="great"></div>
<div id="box2"></div>
js
const box1 = document.getElementById("box1");
const box2 = document.getElementById("box2");

box1.classList.toggle("great");
console.log(box1); //.greatなし

box2.classList.toggle("great");
console.log(box2); //.greatあり

スタイル

スタイルの取得

要素.style.プロパティでは、外部のCSS取得できないので、getComputedStyle(要素ノード).プロパティを使います。

html
 <div id="box">サンプルテキスト</div>
css
#box{
  color:red;
}
js
//.boxを取得
const box = document.getElementById("box");

/計算後のスタイルを取得
console.log(getComputedStyle(box).color); //rgb(255, 0, 0)

スタイルの変更

html
<div id="box" style="color:red">サンプルテキスト</div>
js
const box = document.getElementById("box");

box.style.color = "blue";

スタイルの追加

html
<div id="box" style="color:red">サンプルテキスト</div>
js
const box = document.getElementById("box");

box.style.fontWeight="bold";

スタイルの削除

html
<div id="box" style="color:red">サンプルテキスト</div>
js
const box = document.getElementById("box");

box.style.color = "";

HTML

指定要素内のHTML操作

指定要素内のHTMLの取得

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.getElementById("parent");

console.log(parent.innerHTML);

指定要素内のHTMLの置換

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.getElementById("parent");

parent.innerHTML = "<p>書き換えられたHTML</p>";

指定要素内のHTMLの削除

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.getElementById("parent");

parent.innerHTML = "";

指定要素自体を含むHTML操作

指定要素自体を含むHTMLの取得

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.getElementById("parent");

console.log(parent.outerHTML);

指定要素自体を含むHTMLの置換

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.querySelector(".parent");

parent.outerHTML = "<div id='newParent'><div id='newChild'>書き換えられたHTML</div></div>";

指定要素自体を含むHTMLの削除

html
<div id="parent">
  <div id="child">サンプルテキスト</div>
</div>
js
const parent = document.querySelector(".parent");

parent.outerHTML = "";

DocumentFragment

アクティブなドキュメントツリー構造の一部ではないので、変更を行っても、ドキュメントに影響を与えません。

メソッドの制限

DocumentFragment では使えるメソッドが限られています。

DocumentFragment 内にある要素を取得しようとした場合に使えるメソッド

getElementById()
querySelector()
querySelectorAll()

パフォーマンスへの配慮

ブラウザー再描画の回数を減らすために、すべてのノードを一度DocumentFragmentに集めたあとにドキュメントに追加します。

html
<div id="parent"></div>
js
//親になる要素ノードを取得
const parent = document.getElementById("parent");

//DocumentFragmentを作成
const fragment = document.createDocumentFragment();

//追加する要素ノードを作成
const newDiv = document.createElement("div");

//属性ノードを作成
const newStyle = document.createAttribute("style");
newStyle.value = "color:red";

//テキストノードを作成
const newText = document.createTextNode("あたらしいテキスト");

//DocumentFragmentに、追加する要素ノードを追加
fragment.appendChild(newDiv);

//要素ノードに属性ノードを追加
newDiv.setAttributeNode(newStyle);

//要素ノードにテキストノードを追加
newDiv.appendChild(newText);

//DocumentFragmentを親になる要素ノードに追加
parent.appendChild(fragment);

MutationObserver

DOMの変化を監視して処理を行う事ができます。

オブザーバーの操作

オブザーバーの作成

js
const observer = new MutationObserver(records => {
 //監視対象に変化があったときの処理
})

監視の開始

js
observer.observe(target, {
  //オプションの指定
})

監視の停止

js
observer.disconnect()

サンプル

属性の変化を監視

オプション 無い用 必須/任意
attributes 属性の変化を監視 必須
attributeFilter 監視対象とする属性名を配列で指定 任意
attributeOldValue 変更前の属性を記録 任意
html
<p id="js-target">あああああ</p>
<button id="js-button">ボタン</button>
js
//監視対象の取得
const target = document.querySelector("#js-target");

//observerの作成
const observer = new MutationObserver(records => {
  // 属性が変更されたときの処理
  console.log("属性が変更された");
});

//監視の実行
observer.observe(target, {
  attributes: true,
  attributeFilter: ["class"],
  attributeOldValue: true
});

//監視のテスト用のボタンの取得
 const button = document.querySelector("#js-button");

//ボタンを押すと対象のクラスのトグル
button.addEventListener("click", () => {
  target.classList.toggle("active");
})

文字データの変化を監視

オプション 無い用 必須/任意
characterData 文字データの変化を監視 必須
characterDataOldValue 変更前の文字データを記録 任意
html
<p id="js-target" contenteditable="true">あああああ</p>
js
//監視対象の取得
const target = document.querySelector("#js-target");

//observerの作成
const observer = new MutationObserver(records => {
  //テキストが変更されたときの処理
  console.log("テキストが変更された");
});

//監視の実行
observer.observe(target.childNodes[0], {
  characterData: true
});

子要素リストの変化を監視

オプション 無い用 必須/任意
childList 属性の変化を監視 必須
subtree 子孫ノードも監視対象にする 任意
html
<p id="js-target">あああああ</p>
<button id="js-button">ボタン</button>
js
//監視対象の取得
const target = document.querySelector("#js-target");

//observerの作成
const observer = new MutationObserver(records => {
  // 子要素が変更されたときの処理
  console.log("属性が変更された");
});

//監視の実行
observer.observe(target, {
  childList: true
});

//監視のテスト用のボタンの取得
const button = document.querySelector("#js-button");

//ボタンを押すと監視対象の子要素spanを追加
button.addEventListener("click", () => {
  const child = document.createElement("span");
  target.appendChild(child);
})
30
28
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
30
28