Step 1: Web Basics
02. DOM操作入門:
JavaScriptで画面を操る仕組み
DOM操作は、現在の文書の要素を取得し、その文字・属性・クラスを更新する処理です。猫の手ツールの画像変換では、画像選択・処理中・結果の3画面を、同じHTMLの中で切り替えています。要素の取得から、操作前後の変化を確認する順に進みます。
1. Webページは「木(ツリー)」で構成されている
HTMLファイルは一見すると単なるテキストデータですが、ブラウザがこれを読み込むと、内部で「データ構造」へと変換されます。これを DOM(Document Object Model) と呼びます。
DOMは、Document の下に文書要素の <html> があり、そこから <head> や <body>、さらにその中の <div> や <p> へと枝分かれしていく「ツリー構造」をしています。JavaScriptが画面を書き換えられるのは、このDOMというツリーの中にある特定の枝(要素)を、動的に追加・削除・変更できる権限を持っているからなのです。
2. ターゲットを特定する:getElementById
JavaScriptで何かを操作したいとき、最初に行うべきは「操作対象を特定すること」です。IDで1つの要素を指定するときに使える方法が、HTML要素に付与した一意のIDを頼りに要素を取得する document.getElementById メソッドです。
「猫の手ツール」の開発でも、ユーザーが画像をドラッグ&ドロップするエリアや、処理結果を表示するメッセージボックスを特定するために多用しています。
具体的なコード例:操作の流れ
【HTML側】操作したい要素にIDを振る
<div id="status-message" class="p-4 bg-slate-100">
待機中です...
</div>
<button id="start-btn">処理開始</button> 【JavaScript側】要素を捕まえて内容を書き換える
// 1. IDを頼りに要素を特定して変数に入れる
const messageBox = document.getElementById('status-message');
const btn = document.getElementById('start-btn');
// 2. ボタンが押されたらメッセージと見た目を変える
if (btn && messageBox) {
btn.addEventListener('click', () => {
messageBox.textContent = '処理を開始しました!';
messageBox.classList.remove('bg-slate-100');
messageBox.classList.add('bg-indigo-600', 'text-white');
});
} 3. 元の文書と実行中の状態を分ける
DOMは、読み込んだHTMLから作られた実行中の文書です。設定ファイルと実行中の状態を区別する考え方は、ブラウザでも役立ちます。
- HTML/DOM: 初期状態を記した文書と、それを読み込んだ実行中の構造。DOMは操作によって変わります。
- getElementById: 名前から操作対象を特定する段階。ただしSSHのような通信や認証を行うわけではなく、現在の文書内の要素を探します。
- プロパティの変更: ログイン後に
vimで設定ファイルを書き換えたり、サービスを再起動したりする操作。
要素の取得と状態の変更を分けて読むと、IDの誤りと更新処理の誤りを切り分けやすくなります。
4. 注意点:初心者がハマりやすい落とし穴
対象の要素が存在するか、IDが一意か、HTMLが解析済みかを順に確認します。
IDの重複は厳禁
getElementById は「IDがページ内で唯一であること」を前提としています。もし同じIDを複数の要素に振ってしまうと、ブラウザは最初に見つけた要素しか返しません。複数の要素をまとめて扱うときは、同じIDを使う代わりにクラスや data 属性を付け、querySelectorAll() などで取得します。
要素が存在しない場合(null)のガード
IDの誤記や対象要素の欠落、HTMLがまだ解析されていない場合、getElementById は null を返します。そのまま操作を続けようとすると TypeError でスクリプトが止まってしまいます。
const el = document.getElementById('my-id');
if (el) {
// 要素が存在するときだけ実行する「ガード節」が実務では重要
el.innerText = '安全に変更';
} 画面のDOMと元のHTMLファイルは別
textContent で文章を変更しても、サーバーに置いたHTMLファイルは書き換わりません。再読み込みすれば元の表示に戻ります。ブラウザ内の変更と保存を混同しないことが、設定画面や画像プレビューを作るときの出発点です。
このページのサンプルはHTMLの後に置いたスクリプト、または type="module" のスクリプトで実行します。開発者ツールの「要素」欄で、クリック前後にテキストと class がどう変化したか確認できます。ユーザー入力を文字として表示したい場合は textContent を選び、HTMLとして解釈する innerHTML と区別してください。
画像変換の3画面をclassListで切り替える
画像形式変換ツールのsetUI()は、最初に3領域を非表示へ戻し、指定された領域だけを表示します。前の画面を隠す操作をまとめることで、処理中と結果が同時に表示される状態を避けています。
function setUI(state) {
if (!dropZone || !loadingArea || !resultArea) return;
[dropZone, loadingArea, resultArea].forEach(el => el.classList.add('hidden'));
if (state === 'upload') dropZone.classList.remove('hidden');
if (state === 'loading') loadingArea.classList.remove('hidden');
if (state === 'result') resultArea.classList.remove('hidden');
}これは本番関数の型指定を省いた抜粋で、3つのDOM要素とhiddenのCSSがある前提です。開発者ツールの要素欄で、ファイル選択前後のclassを比較すると処理を追えます。画像変換の制作解説では、その後の画像処理へ進めます。
5. まとめ:ツール開発におけるDOMの役割
「猫の手ツール」では、複雑な画像処理(Canvas)を行っていますが、最終的にユーザーへ「完了しました!」と伝えたり、ダウンロードボタンを表示したりするのは、すべてこの基礎的なDOM操作の積み重ねです。
次は、イベントへ渡す関数をアロー関数で書いたときの違いを確認します。