JavaScript入門 DOM – 画面の値更新及びCSS変更 –
画面の取得・更新
HTMLタグで囲まれた文字列や子要素を取得・変更するときはElementオブジェクトのinnerHTMLやtextContentにアクセスします。innerHTMLやtextContentは良く使用するプロパティです。
タグで囲んだコンテンツの取得、変更
プロパティ | 説明 |
---|---|
innerHTML | 要素内のHTMLを文字列として取得・変更する。HTML取得の場合には、HTMLタグを含む文字列が取得される。また、HTML変更の場合には、HTMLタグがきちんと解釈されて、画面上に表示される。 |
textContent | 要素内のテキストを取得・変更するテキスト取得の場合は、HTMLタグは無視される。また、テキスト変更の場合は、HTMLタグはただの文字列として扱われる。 |
innterText ※非推奨 | 要素内のテキストがレンダリングされた状態で取得・変更される。代わりにtextContentを使用する。 ※画面上に表示されるテキストを保持します。 ※IE独自の実装プロパティで仕様が紛らわしいため、textContentを使う方が良いです。 |
outerText ※非推奨 | innterTextと同じ。代わりにtextContentを使用する |
innerHTML
「HTMLタグの情報も含めて文字列として取得したい場合には、innerHTMLを使います。」また、innerHTMLに対して設定された文字列にhtmlタグが含まれる場合には、ブラウザはHTMLタグをHTMLときちんと解釈して画面上に表示されます。
<body>
<div id="test"><span>Hello World</span></div>
<script>
const testEl = document.querySelector("#test"); //➊Elementの取得
console.log(`innerHTML: ${ testEl.innerHTML }`); //➋innerHTMLの確認
setTimeout(() => {
testEl.innerHTML = "<h1> Good World</h1>"; //➌innerHTMLの変更
}, 2000);
</script>
</body>
❶Elementの取得
#testセレクタで<div id=”test”>・・・</div>部分のElementオブジェクトを取得します。
❷innerHTMLの確認
innerHTMLには、<div id=”test”>・・・</div>で囲まれた部分がHTML文字列として格納されます。
❸innerHTMLの変更
innerHTMLにHTML文字列を設定すると、その内容がHTMLタグとして解釈されて、画面表示が置き換わります。なお、h1タグで文字を囲むと、通常よりも文字サイズが大きく表示されます。これは、HTMLタグごとにあらかじめ決められたスタイルが適用されているためです。
textContent
一方、textContentでは、要素内のテキスト情報のみ(HTMLタグは含まない)が取得されます。また、textContentにHTML文字列を設定した場合には、HTMLタグはただの文字列として扱われます。
<body>
<div id="test"><span>Hello World</span></div>
<script>
const testEl = document.querySelector("#test"); //➊Elementの取得
console.log(`textContent: ${ testEl.textContent }`); //➋textContentの確認
setTimeout(() => {
testEl.textContent = "<h1> Good World</h1>"; //➌textContentの変更
}, 2000);
</script>
</body>
❶Elementの取得
#testセレクタで<div id=”test”>・・・</div>部分のElementオブジェクトを取得します。
❷textContentの確認
textContentには、<div id=”test”>・・・</div>で囲まれた部分が文字列として格納されます。textContentには、HTMLタグは含みません。
❸textContentの変更
このように、innerHTMLやtextContentを使うと、HTML要素の中のコンテンツが置換されます。
<input>要素のテキストはvalue属性で取得
画面の入力欄を表示する場合は、inputというタグを使います。このとき、入力欄の文字を取得・変更したい場合には、value属性の値を使います。
<input type="text" value="入力文字">
<script>
const input = document.querySelector( "input" );
console.log( input.value ); //入力欄に入力されたテキストを取得
>入力文字
input.value = "入力欄の値を変更"; //入力欄のテキストを変更
</script>
要素の作成
新規で要素(Elementオブジェクト)を作成して追加する方法について解説します。
1、document.createElementメソッドを使う
document.createElementメソッドを使うと、DOMツリー上にないElementオブジェクトを新しく作成できます。
<body>
<!-- 新しい要素をここに追加したい -->
<script>
const newDiv = document.createElement( "div" ); //新しく<div>要素を作成
newDiv.textContent = "Hello World"; //作成した<div>要素に文字列を追加
document.body.prepend( newDiv ); //<body>に挿入
</script>
</body>
document.Elementメソッドで作成したElementはquerySelectorなどでDOMツリーから取得したElementと同様の操作を行うことができます。上記の例では、新しく作成したnewDivに対して文字列を設定しています。また、document.body.prepend部分は、bodyタグに要素を挿入するという意味です。
2、ダミー要素のinnerHTMLに作成したいHTMLを挿入する
作成した要素が複雑なHTML構造の場合、createElementですべての要素を1つずつ作成するのは面倒です。そんときに利用できるのが、innerHTMLを使う方法です。innerHTMLで設定したHTML文字列は自動的にElementオブジェクトの構造に変換されるため、HTML文字列からElementオブジェクトを作成できます。
複雑なHTML構造のElementを作成する場合
HTMLタグが入れ子構造になったHTMLを文字列として定義し、htmlStrToElement関数によってElementオブジェクトに変換しています。
<body>
<!-- 新しい要素をここに追加したい -->
<script>
//<body>に挿入したいHTMLの構造を文字列で定義
const htmlStr = `
<article id="article">
<h1 id="article-title">記事のタイトル</h1>
<div class="tag-area">
<span>タグ:</span><span>スポーツ</span><span>バスケ</span>
</div>
<div class="article-body">記事の本文</div>
<div id="recommend">
<h2>おすすめの記事</h2>
<a href="#">他の記事</a>
</div>
</article>
`;
//HTML文字列をElementオブジェクトに変換する関数
function htmlStrToElement( htmlStr ){
const dummDiv = document.createElement("div");
dummDiv.innerHTML = htmlStr;
return dummDiv.firstElementChild;
}
//HTML文字列からElementオブジェクトを取得
const targetNewElement = htmlStrToElement( htmlStr );
document.body.prepend( targetNewElement );
</script>
</body>
innerHTMLを使う方法では、まずダミーの<div>要素を作成して、そのinnerHTMLに対してHTML文字列を代入します。あとは、ダミーで作成した<div>要素の子要素を取り出してあげれば、取得したかったHTMLをElementオブジェクトとして取得できます。
3、templateタグを使う
templateタグを使うと、画面上に表示されないHTMLを記述できます。そのため、開発者が必要になったタイミングで、templateタグ内のHTMLを取得して画面上に追加できます。
<body>
<!-- 新しい要素をここに追加したい -->
<template id="tmpl"><!-- テンプレート内の記述は画面上に表示されない-->
<span>テンプレートHTMLを定義</span>
</template>
<script>
const tmpl = document.querySelector( "#tmpl" );
const targetNewElement = tmpl.content; //テンプレートの中身を確認
document.body.prepend( targetNewElement );
</script>
</body>
templateタグで囲まれてたHTMLをDOMオブジェクトとして取得するには、contentプロパティ(tmpl.content部分)という特別なプロパティにアクセスします。これまで子要素を取得するときにはfirstElementChildプロパティを使ってきましたが、templateタグで囲まれた部分はfirstElementChildで子要素を取得できないことに注意してください。
要素の追加・削除
querySelectorで取得した要素やcreateElementで作成した要素を他の要素に追加するには、次のメソッドを使用します。
メソッド | 説明 | 挿入場所 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element.append (node1[, node2, …]) | 要素(element)内の最後の子要素としてNode(Elementを含むすべての種別のNode)を挿入する。Node以外に文字列の挿入も可能 | <div> <span></span> <!– ここに挿入–> </div> | |||||||||||
element.prepend (node1[, node2, …]) | 要素(Element)内の最初の子要素としてNodeを挿入する。Node以外に文字列の挿入も可能 | <div> <!– ここに挿入–> <span></span> </div> | |||||||||||
element.before (node1[, node2, …]) | 要素(Element)の直前の要素としてNodeを挿入する。Node以外に文字列の挿入も可能 | <!– ここに挿入–> <div> <span></span> </div> | |||||||||||
element.after (node1[, node2, …]) | 要素(Element)の直後の要素としてNodeを挿入する。Node以外に文字列の挿入も可能 | <div> <span></span> </div> <!– ここに挿入–> | |||||||||||
targetElement. insertAdjacentElement( position, element ) | 要素(targetElement)からの相対的な位置(position)を文字列で指定して、Elementオブジェクト(element)を挿入する
| <!– beforebegin–> <div> <!– afterbegin–> <span></span> <!– beforeend–> </div> <!– afterend–> | |||||||||||
targetElement. insertAdjacentHTML( position, htmlStr) | 要素(targetElement)からの相対的な位置(position)を指定して、HTML文字列(htmlStr)を挿入する。HTML文字列は、HTMLに解釈されて画面上に表示される。 position:指定値はinsertAdjacentElementと同じ | 同上 | |||||||||||
targetElement. insertAdjacentText( position, str) | 要素(targetElement)からの相対的な位置(position)を指定して、文字列(Str)を挿入する。HTMLタグは、ただのテキストとして解釈される。 position:指定値はinsertAdjacentElementと同じ | 同上 |
※divタグに対応するElementオブジェクトのメソッドとして呼び出した場合の挿入位置です。具体的には次のように、メソッドを実行したときに要素が挿入される位置を表しています。
divタグに対応するElementメソッド
const div = document.querySelector( "div" );
div.append( 挿入したいNodeや文字列 );
メソッドによって要素(Elementやテキストなど)の挿入を行います。また、これ以外にもappendChildやinsertBeforeといったメソッドがありますが、appendとbeforeのほうが使い勝手がよいため、要素の追加には表のメソッドを使うとよいでしょう。
要素を削除するメソッド
メソッド | 説明 | 削除対象 |
---|---|---|
element.remove() | 自要素(element)を削除する | <div><!– divを削除 –> <span></span> </div> |
removeChildというメソッドもありますが、使い勝手が悪いため、removeメソッドを使いましょう。
DOMツリー上の要素を取得して別の場所に挿入する場合や新しい要素を作成して挿入するときの注意点
1、DOMツリー上の要素の取得・挿入操作は「要素の移動」になる
既存DOMツリー上の要素を取得して、別の場所に挿入した場合には、その要素は元の場所から削除されます。
既存のDOMツリー内の要素は移動される
#source要素を取得して#target要素に挿入していますが、#cource要素が元の場所から削除されます。
<h1 id="target">
<!-- <span>をここに追加したい -->
</h1>
<span id="source">Hello World</span> <!-- 2秒後にこの<span>は削除される -->
<script>
//2秒後に処理を実行
setTimeout( () => {
const targetEl = document.querySelector( "#target" );
const sourceEl = document.querySelector( "#source" );
targetEl.append( sourceEl );
}, 2000 );
</script>
2、同じ要素を2回挿入するときには複製の操作を行う必要がある
1、の例で仮にtargetEl.append( sourceEl );の行を2回記述したとしても、要素が2つ追加されることはありません。これは、ElementオブジェクトがDOMツリー内でユニーク(重複しない)であることに起因します。そのため、sourceElを2回挿入したとしても、1で説明したとおり「要素の移動」とみなされます。もし、同じ要素を複数挿入したい場合には、cloneNodeメソッドでelementオブジェクトを複製します。これは、createElementやtemplateタグを使って要素を作成した場合も同様です。
構文:cloneNodeの記法
let 複製された要素 = 複製元の要素.cloneNode( フラグ );
フラグ:要素を含めるかどうかのフラグです。(true | false)。デフォルトはfalseで、その場合には自要素のタグのみが複製され、その中身の要素は複製されません。trueの場合は、再帰的に子要素、孫要素が複製されます。
cloneNodeによる複製
<ul>
<li>cloneNodeの引数がtrueでこの文字列も複製されます</li>
</ul>
<script>
const ul = document.querySelector("ul");
const li = ul.querySelector( "li" );
for( let i= 0; i < 3; i++ ){
const clone = li.cloneNode( true ); //要素を複製
ul.append( clone );
}
</script>
要素の属性の取得・変更
HTMLタグには、属性を設定できます。たとえば、imgタグにはsrc属性に画像までのパスを設定します。aタグにはリンク先のパスhref属性に設定します。
要素の属性の取得・変更(Elementのメソッド)
メソッド | 説明 |
---|---|
getAttribute( name ) | 属性(name)の値を取得する |
getAttributeNames() | 属性名の一覧を取得する |
setAttribute( name, value ) | 属性(name)に値(value)を設定する |
removeAtrrribute( name ) | 属性(name)を削除する |
toggleAttribute( name ) | 属性(name)の付け外しを行う |
hasAttributes() | 属性を持っているか確認する。何かしらの属性を保持している場合にはtrue、保持していない場合にはfalseを返す |
hasAttribute( name ) | 特定の属性(name)を持っているか確認する。保持している場合にはtrue、保持していない場合にはfalseを返す |
アンカータグのリンク先をgoogleに変更
<a>Google</a>
<script>
const link = document.querySelector( "a" );
link.setAttribute( "href", "https://google.com" );
</script>
データ属性
データ属性は、ユーザーが独自で値を保持するためのHTML属性です。データ属性は、data-*のような形式で表されます。このようにdata-から始まる属性については、一時的にJavaScriptで使用する値を保持していると考えられます。また、JavaScriptからデータ属性へアクセスするときは、datasetという特別なプロパティを通してアクセスします。なお、属性値は文字列として取得されるため、数値を扱いたい場合にはNumberなどを使って数値を変換します。
データ属性の取得・変更
<div id="sum" data-base-val1="10" data-base-val2="20" ></div>
<script>
const sum = document.querySelector( "#sum" );
const val1= parseInt( sum.dataset.baseVal1 ); //データ属性を取得
const val2= parseInt( sum.dataset.baseVal2 ); //"_"はキャメルケースとして表現する
sum.dataset.sumVal = val1 + val2; //データ属性の追加も可能
sum.textContent = val1 + val2;
</script>
スタイルの変更
JavaScriptでスタイルを追加、変更する方法を説明します。
構文:style属性の変更
Elementオブジェクト.style.CSSプロパティ名 = 設定したい値;
- Elementオブジェクト:スタイル(見栄え)を変更したい要素
- CSSプロパティ名:CSSのプロパティ名を設定します。たとえば、文字色を変更したい場合には、colorになります。※ハイフン(-)をはさむプロパティ名では、キャメルケースを使います。たとえば、CSSのbackground-colorプロパティの値を操作したい場合には、Elementオブジェクト.style.backgroundColorの値を変更します。
styleプロパティから文字色と背景色を変更
<div>2秒後に文字と背景の色が変わります。</div>
<script>
setTimeout( () => {
const div = document.querySelector( "div" );
div.style.color = "red"; //文字色を赤色に変更
div.style.backgroundColor = "blue"; //背景色を青色に変更
} ,2000); //2秒後にコールバック関数を実行
</script>
classListを使ったスタイルの変更
スタイル適用するときは、class属性の値をセレクタで指定します。そのため、class属性の付け外しをJavaScriptから操作することで、画面上のデザインを変更することができます。JavaScriptからclass属性の値を操作する場合には、ElementオブジェクトのclassListプロパティに格納されているメソッドを使用します。
構文:class属性の値を変更するメソッド
■class属性にクラス(className)を追加する
Elementオブジェクト.classList.add( "className" );
<div class=""> → <div class="className">
■class属性にクラス(className)を削除する
Elementオブジェクト.classList.remove( "className" );
<div class="className"> → <div class="">
■class属性にクラス(className)を付け外しする
Elementオブジェクト.classList.toggle( "className" );
<div class=""> ← 呼び出しごとにクラスの付け外し → <div class="className">
■クラスがclass属性内に存在するか確認
Elementオブジェクト.classList.remove( "className" ); //存在する場合はtrueが返る
classListを使ったスタイルの変更
<div>2秒後に文字と背景の色が変わります。</div>
<style>
/* 付与する予定のスタイルをCSSであらかじめ定義 */
.preparedClass {
color: red;
background-color: blue;
}
</style>
<script>
setTimeout( () => {
const div = document.querySelector( "div" );
div.classList.add( "preparedClass" ); //preparedClassという文字列をcalss属性に追加する
} ,2000); //2秒後にコールバック関数を実行
</script>