document と window の違いは?#
簡単に言えば、dom はオブジェクトであり、win もオブジェクトです。彼らは Web API の中で異なる役割を持っています。
window オブジェクト#
- window オブジェクト
window はウィンドウを指し、ブラウザのウィンドウまたはタブを表し、JavaScript のグローバルオブジェクトです。ブラウザウィンドウを制御するための多くのメソッドとプロパティを提供します。
スコープ:window は最上位のオブジェクトであり、ブラウザ内の任意の JavaScript コードから直接 window およびそのプロパティやメソッドにアクセスできます。
機能:window オブジェクトはブラウザウィンドウのプロパティ(ウィンドウのサイズ、位置など)を含み、また新しいウィンドウを開く、タイマー関数(setTimeout、setInterval)、ブラウザの履歴を制御するなどのウィンドウの動作を制御するためのメソッドを提供します。さらに、全てのグローバル変数とグローバル関数のホストでもあります。
document オブジェクト#
- document オブジェクト
定義:document オブジェクトは window オブジェクトのプロパティであり、ウィンドウに読み込まれた HTML ドキュメントを表し、Document Object Model(DOM)のエントリポイントです。
スコープ:document オブジェクトはドキュメントの内容を操作およびアクセスするために特化されています。例えば、HTML 要素、CSS スタイルなどです。
機能:document オブジェクトはドキュメントの内容にアクセスおよび変更するための多くのメソッドを提供します。要素の内容を取得および設定する、新しい HTML 要素を作成する、クエリセレクタを使用するなどです。document オブジェクトを通じて、ページの内容を動的に変更し、インタラクションを実現できます。
全体として、window オブジェクトはブラウザウィンドウ自体を表し、全てのグローバル JavaScript オブジェクト、関数、変数の親オブジェクトであり、document オブジェクトはウィンドウに読み込まれたドキュメントを表し、全ての HTML ドキュメント要素のコンテナです。実際の開発では、ブラウザウィンドウ自体を操作するのか、ウィンドウ内のドキュメント内容を操作するのかに応じて、window または document を使用することが決まります。
簡単に言えば、dom オブジェクトはドキュメントの内容を操作し、window オブジェクトはブラウザウィンドウのプロパティとメソッドを操作します。したがって、タイマーを設定したり、ウィンドウの変化を監視したりしたい場合は window オブジェクトを使用する必要がありますが、ドキュメントの内容を変更したい場合は document オブジェクトを使用する必要があります。
そのため、実際にはガントチャートの最も重要な問題は、window API と document API の違いがわからなかったことです。私はネイティブの HTML を理解しておらず、この知識が欠けていると、自然にこのロジックを設計することはありません。
本質的には、パッケージ化された API を使うことができるということです。
Dom 流 API 学習#
要素の取得方法#
DOM で要素を取得する主な API は以下の通りです:
-
getElementById()- 要素の ID を使用して単一の要素を取得します。ID は HTML ドキュメント内で一意である必要があります。
let element = document.getElementById('elementId'); // IDを使用して要素を取得 -
getElementsByClassName()- 要素のクラス名を使用して要素の集合を取得します。このメソッドは、指定されたクラス名に一致する全ての要素を含む類似配列オブジェクトを返します。
let elements = document.getElementsByClassName('className'); // クラス名を使用して要素の集合を取得 -
getElementsByTagName()- 要素のタグ名(例えば
div,p,aなど)を使用して要素の集合を取得します。同様に、指定されたタグ名に一致する全ての要素を含む類似配列オブジェクトを返します。
let elements = document.getElementsByTagName('tagName'); // タグ名を使用して要素の集合を取得 - 要素のタグ名(例えば
-
querySelector()- CSS セレクタを使用して最初に一致する要素を取得します。これは非常に強力なメソッドで、複雑な CSS セレクタを使用して要素を特定できます。
let element = document.querySelector('.className'); // CSSセレクタを使用して最初に一致する要素を取得 -
querySelectorAll()- CSS セレクタを使用して全ての一致する要素の集合を取得します。このメソッドは、指定された CSS セレクタに一致する全ての要素を含む
NodeListオブジェクトを返します。
let elements = document.querySelectorAll('.className'); // CSSセレクタを使用して全ての一致する要素を取得 - CSS セレクタを使用して全ての一致する要素の集合を取得します。このメソッドは、指定された CSS セレクタに一致する全ての要素を含む
-
closest()- 要素自身から始めて、その祖先要素の中で(自身を含む)、指定された CSS セレクタに一致する最初の要素を見つけます。このメソッドは、要素の最近の親の一致を見つけるのに非常に便利です。下から上に探します。
let closestElement = element.closest('.className'); // 要素の祖先の中で最近の指定されたセレクタに一致する要素を見つける -
children- 要素の子要素の集合を取得します。テキストノードやコメントノードは含まれません。これは要素オブジェクトのプロパティで、直接の子要素の HTML 集合を返します。
let childElements = parentElement.children; // parentElementの全ての直接の子要素を取得 -
childNodes- 要素の全ての子ノードを取得します。要素ノード、テキストノード、コメントノードを含みます。これも要素オブジェクトのプロパティで、ノードリストを返します。
let childNodes = parentElement.childNodes; // parentElementの全ての子ノードを取得(テキストとコメントを含む) -
parentElementとparentNode- 要素の親要素を取得します。
parentElementは親要素ノードを返し、parentNodeはテキストノードやコメントノードを含む任意のタイプの親ノードを返すことができます。
let parent = childElement.parentElement; // childElementの親要素を取得 let parentNode = childElement.parentNode; // childElementの親ノードを取得 - 要素の親要素を取得します。
-
nextSiblingとpreviousSibling- 要素の次の同級ノードと前の同級ノードをそれぞれ取得します。これらのプロパティが返すのは、要素ノード、テキストノード、コメントノードを含む任意のタイプのノードです。
let nextNode = element.nextSibling; // elementの次の同級ノードを取得 let prevNode = element.previousSibling; // elementの前の同級ノードを取得 -
nextElementSiblingとpreviousElementSiblingnextSiblingとpreviousSiblingに似ていますが、これらのプロパティは要素ノードのみを返し、テキストノードやコメントノードは無視します。
let nextElement = element.nextElementSibling; // elementの次の同級要素を取得 let prevElement = element.previousElementSibling; // elementの前の同級要素を取得 -
firstChildとlastChild- 要素の最初の子ノードと最後の子ノードをそれぞれ取得します。これらの子ノードは、要素ノード、テキストノード、コメントノードを含む任意のタイプのノードです。
let first = parentElement.firstChild; // parentElementの最初の子ノードを取得 let last = parentElement.lastChild; // parentElementの最後の子ノードを取得 -
firstElementChildとlastElementChildfirstChildとlastChildに似ていますが、これらのプロパティは要素ノードのみを返し、テキストノードやコメントノードは無視します。
let firstElement = parentElement.firstElementChild; // parentElementの最初の子要素を取得 let lastElement = parentElement.lastElementChild; // parentElementの最後の子要素を取得
これらの API を総合的に活用することで、DOM ツリーを効果的に遍歴し、操作し、ページ構造を柔軟に制御できます。
これらの API を使用することで、異なる条件やニーズに応じて、DOM ツリー内で単一または複数の要素を柔軟に取得できます。
要素の作成方法#
要素を作成する#
document.createElement('tag')
テキストノードを作成する#
document.createTextNode('text')
テキストノードとは何ですか?
テキストノードは HTML 内のテキストであり、例えば p タグ内のテキストや a タグ内のテキストなどです。
createTextNode はどのように使用しますか?
var text = document.createTextNode('text')
これはどのような効果ですか?
<p>text</p>
ここでの text はその文字の内容です。
要素を追加する方法#
要素を追加する#
parent.appendChild(child)
これはどのような効果ですか?
<div>
<p>text</p>
</div>
要素を挿入する#
parent.insertBefore(newNode, referenceNode)
例を挙げると
var parent = document.getElementById('parent')
var newNode = document.createElement('p')
var referenceNode = document.getElementById('reference')
parent.insertBefore(newNode, referenceNode)
これはどのような効果ですか?
<div id="parent">
<p>newNode</p>
<p id="reference">referenceNode</p>
</div>
referenceNode はどのような役割を果たしますか?
referenceNode は参照ノードであり、参照ノードの前に新しいノードを挿入する役割を果たします。
要素を削除する方法#
要素を削除する#
parent.removeChild(child)
例を挙げると
var parent = document.getElementById('parent')
var child = document.getElementById('child')
parent.removeChild(child)
これはどのような効果ですか?対比を示してください
<div id="parent">
<p id="child">child</p>
</div>
<div id="parent">
</div>
要素の内容を変更する方法は?#
DOM(文書オブジェクトモデル)で要素の内容を変更する主な API は以下の通りです:
-
innerTextとtextContent
これらのプロパティは、要素のテキスト内容を取得または設定するために使用できます。innerTextは要素とその子要素の「レンダリング」されたテキスト内容を反映し、textContentは要素内の全ての子ノードの内容を取得または設定します。element.innerText = '新しいテキスト内容'; // 要素の可視テキストを設定 let content = element.innerText; // 要素の可視テキストを取得 element.textContent = '新しい全てのテキスト内容'; // 要素の全てのテキストを設定、全ての子ノードを含む let fullContent = element.textContent; // 要素の全てのテキストを取得、全ての子ノードを含む -
innerHTML
innerHTMLプロパティは、要素内の HTML 内容を取得または設定するために使用できます。innerTextやtextContentとは異なり、innerHTMLは全ての HTML タグを含みます。element.innerHTML = '<strong>太字のテキスト</strong>'; // 要素内のHTML内容を設定 let htmlContent = element.innerHTML; // 要素内のHTML内容を取得 -
outerHTML
outerHTMLプロパティは、要素自身とその全ての子ノードを含む HTML を取得または設定できます。element.outerHTML = '<div><strong>新しい要素とその内容</strong></div>'; // 要素とその内容を置き換える -
createElementとappendChild/replaceChild
これらのメソッドは、新しい DOM 要素を作成し、文書に挿入するために使用されます。createElementは新しい要素ノードを作成し、appendChildは作成したノードを親ノードの子ノードリストの末尾に追加し、replaceChildは親ノードの子ノードを置き換えます。let newElement = document.createElement('div'); // 新しいdiv要素を作成 newElement.innerText = 'これは新しく作成された要素です'; // 新要素のテキスト内容を設定 parentElement.appendChild(newElement); // 新要素をparentElementの子ノードとして追加 let anotherElement = document.createElement('span'); // 別の要素を作成 parentElement.replaceChild(anotherElement, newElement); // 親要素内の子要素を置き換える
これらの API を使用することで、DOM 内の要素の内容や構造を簡単に変更できます。
DOM 内の要素のスタイルや属性を変更する主な API は以下の通りです:
-
スタイルの変更:
styleプロパティ- 各 DOM 要素には
styleプロパティがあり、JavaScript を通じて要素のスタイルを直接変更できます。要素のstyleプロパティ内の CSS プロパティを設定することでスタイルを変更できます。
element.style.backgroundColor = 'red'; // 要素の背景色を赤に設定 element.style.fontSize = '20px'; // 要素のフォントサイズを20ピクセルに設定 - 各 DOM 要素には
-
クラスの変更:
classListプロパティclassListは、要素のクラス名の集合を操作するための簡単な方法を提供します。一般的なメソッドにはadd()、remove()、toggle()、contains()があります。
element.classList.add('new-class'); // 新しいクラス名を追加 element.classList.remove('old-class'); // クラス名を削除 element.classList.toggle('active'); // 存在すればそのクラス名を削除し、存在しなければ追加 -
属性の設定と取得:
setAttribute()とgetAttribute()- これらのメソッドは、要素の属性を設定および取得するために使用されます。属性は標準の HTML 属性(例えば
id、src、hrefなど)やカスタム属性である可能性があります。
element.setAttribute('data-custom', 'value'); // カスタム属性を設定 let value = element.getAttribute('data-custom'); // このカスタム属性の値を取得 - これらのメソッドは、要素の属性を設定および取得するために使用されます。属性は標準の HTML 属性(例えば
-
属性を直接変更
id、src、hrefなどの一般的な HTML 属性については、要素オブジェクトを通じて直接取得および設定できます。
element.href = 'https://example.com'; // 要素のhref属性を直接設定 let elementId = element.id; // 要素のid属性を直接取得
これらの API を使用することで、JavaScript 内で DOM 要素のスタイルや属性を簡単に変更し、動的なページ効果を実現できます。
要素を置き換える方法#
要素を置き換える#
DOM 操作における要素の置き換えには、以下の一般的な API が含まれます:
-
replaceChild(newChild, oldChild)- これは親ノード上で呼び出されるメソッドで、親ノード内の旧子ノードを新しい子ノードに置き換えるために使用されます。
newChildは挿入する新しいノードで、oldChildは置き換えられる旧ノードです。
parentNode.replaceChild(newElement, oldElement); // parentNode内のoldElementをnewElementに置き換える - これは親ノード上で呼び出されるメソッドで、親ノード内の旧子ノードを新しい子ノードに置き換えるために使用されます。
-
replaceWith(...)replaceWith()メソッドは、指定されたノードまたは HTML やテキスト文字列を使って DOM ノード(または複数のノード)を置き換えることを可能にします。このメソッドは、置き換えられるノード上で直接呼び出されます。
oldElement.replaceWith(newElement); // oldElementをnewElementに置き換える -
insertBefore()とremoveChild()またはremove()を組み合わせて置き換えを実現- 直接的な置き換えメソッドではありませんが、新しいノードを旧ノードの前に挿入し、その後旧ノードを削除することで置き換えを実現できます。
parentNode.insertBefore(newElement, oldElement); // newElementをoldElementの前に挿入 parentNode.removeChild(oldElement); // oldElementを削除し、置き換え効果を実現 // または、環境がサポートしている場合は、より簡潔にoldElement.remove()を使用できます。 oldElement.remove(); -
outerHTMLを使用- 要素の
outerHTMLプロパティを設定することで、要素自身とその内容全体を直接置き換えることができます。この方法では、親ノードを取得する必要はありません。
oldElement.outerHTML = '<div id="newElement">新しい内容</div>'; // oldElementを新しいHTML内容で置き換える - 要素の
これらの API は、DOM 内の要素を置き換える柔軟な方法を提供し、異なるシナリオやニーズに応じて適切な方法を選択できます。
要素にイベントを追加する方法#
DOM 内で要素のイベントを処理する主な API は以下の通りです:
-
addEventListener(event, handler, [options])- 指定された要素にイベントリスナーを追加するために使用されます。
eventはリッスンするイベントタイプ(例えば"click"、"mouseover"など)、handlerはイベントが発生したときに呼び出される関数、optionsは詳細なイベントリスニング動作を指定するためのオプションのパラメータです。
element.addEventListener('click', function() { console.log('要素がクリックされました'); }); - 指定された要素にイベントリスナーを追加するために使用されます。
-
removeEventListener(event, handler, [options])- 以前に
addEventListenerで追加したイベントリスナーを削除するために使用されます。handlerは、リスナーを追加したときに使用した同じ関数参照でなければなりません。
function handleClick() { console.log('要素がクリックされました'); } element.addEventListener('click', handleClick); // 後でリスナーを削除 element.removeEventListener('click', handleClick); - 以前に
-
dispatchEvent(event)- 指定された要素上でイベントをトリガーするために使用されます。
eventはEventオブジェクトのインスタンスであり、new Event()を使用して作成できます。
let event = new Event('customEvent'); element.dispatchEvent(event); // カスタムイベントをトリガー - 指定された要素上でイベントをトリガーするために使用されます。
-
プロパティを通じてイベントハンドラーを直接割り当てる
- 要素のイベントハンドラー属性にイベント処理関数を直接割り当てることができます。例えば、
onclickはクリックイベントに対応します。
element.onclick = function() { console.log('要素がクリックされました'); }; - 要素のイベントハンドラー属性にイベント処理関数を直接割り当てることができます。例えば、
-
onプレフィックスの属性を使用してイベント処理関数を設定onclickの他にも、onmouseover、onkeydownなど、onで始まる属性を設定することで多くの他のイベントに対して処理関数を追加できます。
element.onmouseover = function() { console.log('マウスが要素の上にあります'); }; -
Eventオブジェクトの使用- イベント処理関数内の
eventパラメータはEventオブジェクトのインスタンスであり、イベントに関する情報(イベントが発生した要素、イベントタイプ、その他の特定のイベントに関連するプロパティやメソッド)を提供します。
element.addEventListener('click', function(event) { console.log('クリックが発生したのは ' + event.target.tagName + ' 要素上です'); }); - イベント処理関数内の
-
preventDefault()- イベントオブジェクトの
preventDefault()メソッドは、イベントのデフォルトの動作を防ぐために使用されます。これは、リンクをクリックしたときにページがジャンプしないようにしたり、フォームを送信したときにページが再読み込みされないようにする場合に非常に便利です。
element.addEventListener('click', function(event) { event.preventDefault(); // リンクのデフォルトのジャンプ動作を防ぐ }); - イベントオブジェクトの
-
stopPropagation()- イベントが親要素にバブルアップするのを防ぐために使用されます。イベントバブリングとは、イベントが最も深いノードから始まり、次第に浅いノードに向かって伝播するプロセスを指します。
element.addEventListener('click', function(event) { event.stopPropagation(); // イベントのバブリングを停止 }); -
イベント委任
- イベントバブリングの特性を利用して、各子要素ではなく親要素にイベントリスナーを設定できます。イベントが子要素で発生し、親要素にバブリングすると、イベントの
target属性を確認してどの子要素がイベントをトリガーしたかを特定できます。
parentElement.addEventListener('click', function(event) { if (event.target && event.target.matches('button.child')) { console.log('子ボタンがクリックされました'); } }); - イベントバブリングの特性を利用して、各子要素ではなく親要素にイベントリスナーを設定できます。イベントが子要素で発生し、親要素にバブリングすると、イベントの
-
captureイベントキャプチャ- イベント処理の第 3 のパラメータ
optionsで、captureをtrueに設定することで、イベント処理器がバブリング段階ではなくキャプチャ段階で実行されるように指定できます。イベントキャプチャは、イベントが最外層から始まり、次第に深いノードに向かって伝播するプロセスを指します。
element.addEventListener('click', function() { console.log('キャプチャ段階のイベント処理'); }, {capture: true}); - イベント処理の第 3 のパラメータ
-
onceオプションaddEventListenerの第 3 のパラメータで、once: trueを設定することで、イベント処理器が一度だけ実行され、その後自動的に削除されます。
element.addEventListener('click', function() { console.log('このイベント処理器は一度だけ実行されます'); }, {once: true});
これらの API を使用することで、DOM 要素に対してイベントを柔軟に追加、削除、トリガーし、豊富なインタラクション効果を実現できます。
ライフサイクル#
DOM(文書オブジェクトモデル)と Window オブジェクトは、Web ページのライフサイクルにおいて重要な役割を果たします。以下に、DOM と Window のライフサイクルに関連する API を紹介します:
-
Window のライフサイクルイベント:
-
loadイベント- ページ全体とすべての依存リソース(スタイルシートや画像など)が完全に読み込まれたとき、
windowオブジェクトはloadイベントをトリガーします。
window.addEventListener('load', function() { console.log('ページが完全に読み込まれました'); }); - ページ全体とすべての依存リソース(スタイルシートや画像など)が完全に読み込まれたとき、
-
DOMContentLoadedイベント- 初期の HTML ドキュメントが完全に読み込まれ、解析が完了したとき、スタイルシート、画像、子フレームの読み込みを待つ必要はなく、
documentオブジェクトはDOMContentLoadedイベントをトリガーします。
document.addEventListener('DOMContentLoaded', function() { console.log('DOM内容が読み込まれました'); }); - 初期の HTML ドキュメントが完全に読み込まれ、解析が完了したとき、スタイルシート、画像、子フレームの読み込みを待つ必要はなく、
-
unloadイベント- ユーザーが現在のページを離れると、
windowオブジェクトはunloadイベントをトリガーします。このイベントは、ポップアップウィンドウを閉じるなどのクリーンアップ作業に使用できます。
window.addEventListener('unload', function() { console.log('ユーザーがページを離れました'); }); - ユーザーが現在のページを離れると、
-
beforeunloadイベント- ウィンドウ、ドキュメント、またはそのリソースがアンロードされる直前にトリガーされます。ユーザーに現在のページを離れるかどうかを確認するために使用でき、通常は未保存の変更を保存するようにユーザーに通知します。
window.addEventListener('beforeunload', function(event) { event.returnValue = '未保存の変更があります。離れてもよろしいですか?'; });
-
-
リクエストアニメーションフレーム(Request Animation Frame):
-
requestAnimationFrame(callback)- ブラウザが再描画する前に特定のコードを呼び出す方法を提供し、アニメーションやページの再描画などを実行するために使用されます。このメソッドは、従来の
setIntervalよりも効率的で、アニメーションをよりスムーズに実行できます。
function animate() { // アニメーションコード requestAnimationFrame(animate); } requestAnimationFrame(animate); - ブラウザが再描画する前に特定のコードを呼び出す方法を提供し、アニメーションやページの再描画などを実行するために使用されます。このメソッドは、従来の
-
-
ページ可視性 API(Page Visibility API):
- この API は、
visibilitychangeイベントとdocument.hidden属性を提供し、ページがユーザーに対して可視かどうかを検出するために使用されます。これは、ページのパフォーマンスとユーザーエクスペリエンスを最適化するのに特に役立ちます。例えば、ページが見えないときに動画の再生を一時停止したり、アニメーションを停止したりできます。
document.addEventListener('visibilitychange', function() { if (document.hidden) { console.log('ページが見えなくなりました'); } else { console.log('ページが見えるようになりました'); } }); - この API は、
-
パフォーマンス監視 API(Performance API):
performanceオブジェクトは、現在のページに関連するパフォーマンスデータにアクセスすることを許可します。例えば、performance.timingを使用して、ページの読み込み、解析などの異なる段階の時間を分析できます。
window.addEventListener('load', function() { setTimeout(function() { const timing = performance.timing; const loadTime = timing.loadEventEnd - timing.navigationStart; console.log('ページの読み込み時間:' + loadTime); }, 0); }); -
resizeイベント:- ブラウザウィンドウのサイズが変更されると、
windowオブジェクトはresizeイベントをトリガーします。これは、ページのレイアウトを調整したり、ウィンドウサイズの変化に応じて他の操作を実行するために使用できます。
window.addEventListener('resize', function() { console.log('ウィンドウのサイズが変更されました'); }); - ブラウザウィンドウのサイズが変更されると、
-
scrollイベント:- ユーザーがページをスクロールすると、
scrollイベントがトリガーされます。これは、「遅延読み込み」(画像などのコンテンツを遅れて読み込む)を実現したり、ナビゲーションバーのスタイルを動的に変更したりするために使用できます。
window.addEventListener('scroll', function() { console.log('ページがスクロールされました'); }); - ユーザーがページをスクロールすると、
-
focusとblurイベント:- ページまたはページ内の要素がフォーカスを得たり失ったりすると、
focusとblurイベントがトリガーされます。これは、フォーム入力のユーザーエクスペリエンスを改善したり、アプリケーション内でキーボードショートカットを管理したりするために使用できます。
window.addEventListener('focus', function() { console.log('ウィンドウがフォーカスを得ました'); }); window.addEventListener('blur', function() { console.log('ウィンドウがフォーカスを失いました'); }); - ページまたはページ内の要素がフォーカスを得たり失ったりすると、
これらの API を組み合わせて使用することで、開発者は Web アプリケーションの動作とパフォーマンスをより細かく制御し、ユーザーのインタラクション体験を向上させることができます。
これらのライフサイクルイベントをリッスンし、処理することで、Web ページの読み込み、レンダリング、アンロードプロセスをより良く制御し、ユーザーエクスペリエンスを向上させることができます。