Javaを学び終えた新人エンジニアのみなさんがJavaScriptを学ぶことには、以下の4つの意義があります。
- フロントエンド開発への応用力が高まる
Javaが主にサーバーサイドで利用されるのに対し、JavaScriptはフロントエンド開発に欠かせない言語です。JavaScriptを習得することで、より広い技術分野において知識を有するエンジニアとしてシステム全体を設計・実装できるようになり、技術の幅が大きく広がります。 - 設計思想の違いを理解できる
Javaは静的型付け言語で、型が厳密にチェックされるのに対し、JavaScriptは動的型付け言語で柔軟に記述できます。この違いはバグの出方や設計手法にも影響します。異なる型システムに触れることで、より柔軟かつ堅牢なコード設計が可能になります。また、Javaはコンパイラ型で事前にバイトコードに変換され、JavaScriptはインタプリタ型で逐次実行されます。こうした実行モデルの違いを知ることで、アプリケーションの性能や開発体験にも敏感になり、適切な技術選定ができるようになります。 - TypeScriptやNode.jsを通じて、フルスタック開発に対応できる
JavaScriptの知識をさらに広げると、型安全性を持つTypeScriptや、JavaScriptでサーバーサイド開発を可能にするNode.jsといった技術に触れることができます。これにより、Javaの知識と組み合わせてフロントエンドからバックエンドまで一貫したシステム開発が可能になり、現代の開発現場で重宝される存在になれます。
JavaScriptを学ぶことで、視野が広がり、より多角的な開発スキルを身につけることができるのです。
この講座の目標
以下の名前入力フォームのJavaScript部分を読んで何をしているのかが理解できるレベルを目指します。
JavaScriptを使ったWebページには以下のような一定の型があります。
「DOM要素を取得→イベントを登録→繰り返しや条件分岐→表示更新」
document.addEventListener('DOMContentLoaded', () => {
// ① DOM要素の取得
const form = document.getElementById('signup-form');
const usernameInput = document.getElementById('username');
const message = document.getElementById('message');
// ② フォーム送信時の処理
form.addEventListener('submit', (e) => {
e.preventDefault(); // ページのリロードを防止
const name = usernameInput.value.trim();
// ③ 入力チェック
if (name === '') {
showMessage('名前を入力してください', 'error');
return;
}
// ④ 成功メッセージの表示
showMessage(`ようこそ、${name}さん!`, 'success');
// ⑤ フォームのリセット(任意)
form.reset();
});
// ⑥ メッセージ表示用の関数
function showMessage(text, type) {
message.textContent = text;
message.className = `message ${type}`; // class を上書き
}
});
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>名前入力フォーム</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<h1>ユーザー登録</h1>
<form id="signup-form">
<label for="username">名前:</label>
<input type="text" id="username" />
<button type="submit">送信</button>
</form>
<p id="message" class="message"></p>
<script src="script.js"></script>
</body>
</html>
.message {
margin-top: 10px;
padding: 8px;
display: inline-block;
}
.success {
color: green;
border: 1px solid green;
}
.error {
color: red;
border: 1px solid red;
}
JavaScriptはボディの閉じタグの直前に書かれることが一般的です。HTMLを読み込んだあとに実行したいためです。
1. DOMを操作するJavaScriptの定番の流れ
① DOMの読み込みを待つ(必須)
document.addEventListener('DOMContentLoaded', () => {
// ここに初期化処理を書く
});
- HTMLが完全に読み込まれる前にJavaScriptが実行されると、要素が取得できないことがある。
- そのため、初期処理は
DOMContentLoaded
イベントで囲むのが安全。
② DOM要素を取得する
const button = document.getElementById('submit-button');
const input = document.querySelector('#name');
- 目的の要素にアクセスするために
getElementById
やquerySelector
で取得。 - 変数名は「何を操作するか」がわかるようにするのが定番。
③ イベントリスナーを登録する
button.addEventListener('click', () => {
// クリック時の処理
});
- 典型的なユーザー操作(クリック、入力、送信など)に対応。
- コールバック関数はアロー関数でその場に書くか、別関数に切り出して再利用する。
④ 状態に応じた処理を行う(検証、条件分岐など)
if (input.value.length < 5) {
alert('5文字以上入力してください');
}
- DOMから取得した値を検証し、分岐処理を実行。
- 状態に応じて表示要素を書き換える処理などが続く。
⑤ DOMの見た目や中身を更新する
document.querySelector('#message').textContent = '送信完了';
document.querySelector('#message').classList.add('visible');
textContent
,innerHTML
,classList
,style
などで表示を操作。- 特に最近はクラスのON/OFFで状態を切り替える手法が一般的。
2. 関数宣言
Javaのメソッドはクラスに属し、型やアクセス修飾子が必須でした。一方JavaScriptの関数は独立して定義でき、アロー関数ではfunction
キーワードすら不要で簡潔です。
特にアロー関数は「外側のスコープのthis
を引き継ぐ」特徴があり、コールバック関数やイベント処理で便利です。通常の関数ではthis
は呼び出し元に依存しますが、アロー関数では定義時のthis
を保持するため、クラス内やDOM操作での意図しないthis
の変化を防げます。Javaでは常にthis
は自身のインスタンスを指すのと対照的です。
JavaScriptでは関数を宣言する方法が複数あり、主に以下の2つが使われます。
1. 関数宣言(Function Declaration)
function greet() {
console.log('Hello');
}
特徴
- 巻き上げ(Hoisting)される
→ スクリプト内で定義より前でも呼び出せる。 - よりグローバルやロジックの基本部分に向いている。
使うべき場面
- 明確に何度も呼び出す処理を定義したいとき。
- コード構造を読みやすく整理したいとき。
- イベント外などスコープの最上位で使いたいとき。
2. 関数式(Function Expression)
const greet = function () {
console.log('Hello');
};
またはアロー関数で:
const greet = () => {
console.log('Hello');
};
特徴
- Hoistingされない
→ 定義より前では呼び出せない。 const
やlet
と組み合わせて、関数を変数に代入できる。
使うべき場面
- イベントリスナーのようにその場で関数を渡す場合。
- スコープを限定したい処理(モジュール内や関数内など)。
- 関数を値として扱う処理(例:コールバック、配列処理
map
,filter
など)。
まとめ(理解のポイント)
項目 | 関数宣言 | 関数式(アロー含む) |
---|---|---|
巻き上げ | される | されない |
再利用性 | 高い(複数箇所で使う) | 低い(使い捨てが多い) |
スコープの制御 | あまり強くない | const /let と合わせて制御できる |
主な用途 | 汎用的な処理 | イベント・コールバック・クロージャ |
何をどこで使うのかによって、「使い捨て」か「再利用」かを意識して選ぶと良いでしょう。
第1章 JavaScriptとは?
1-1. JavaScriptの立ち位置を理解しよう
JavaScriptは、Webページに動きを与えるためのプログラミング言語です。HTMLやCSSが「構造」と「見た目」を担当するのに対し、JavaScriptはユーザーの操作に応じたインタラクティブな動作を実現します。
Web開発の三本柱
技術 | 役割 | 例 |
---|---|---|
HTML | 構造 | 見出し、段落、リンクなど |
CSS | 見た目 | 色、フォント、レイアウト |
JavaScript | 動き・機能 | ボタンクリック時の処理、入力チェック、アニメーション |
これらを組み合わせることで、モダンなWebアプリケーションが実現されています。
1-2. フロントエンドとバックエンドの違い
フロントエンド
- ユーザーが直接見る部分(ブラウザ上で表示されるHTML/CSS/JavaScript)
- JavaScriptで実装される処理:ボタンクリック、バリデーション、非同期通信など
バックエンド
- サーバー側で動作する処理(Java, Python, PHP など)
- Spring Bootなどのフレームワークが使われる
【例】
フォームに入力 → JavaScriptで入力チェック → サーバーに送信 → Spring Bootがデータを処理 → 結果を画面に表示
フロントエンドとバックエンドは、役割分担して連携しています。
1-3. JavaとJavaScriptは全くの別物!
名前は似ていますが、JavaとJavaScriptは全く異なる言語です。
比較項目 | Java | JavaScript |
---|---|---|
実行環境 | JVM(サーバー、PCなど) | Webブラウザ |
用途 | サーバー処理、業務アプリ等 | Webの画面処理、動的なUI |
型付け | 静的型付け | 動的型付け |
クラスベース | ○ | ES6からはクラスあり(本質はプロトタイプ) |
Javaの経験があると、文法面で親しみやすい部分はありますが、根本的な考え方が違うため、最初は混乱しないように注意が必要です。
1-4. JavaScriptはブラウザで動く!
JavaScriptの最大の特徴は「ブラウザ上で即時実行できる」ことです。
ブラウザに組み込まれたJavaScriptエンジン
- Chrome → V8エンジン
- Firefox → SpiderMonkey
- Safari → JavaScriptCore(Nitro)
つまり、インストール不要で、すぐに試せるのが魅力です。開発者ツール(F12)を使えば、その場でコードを試せます。
<!-- HTMLに直接JavaScriptを埋め込む例 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button onclick="alert('こんにちは')">クリックしてみて!</button>
</body>
</html>
第2章 JavaScriptの基本文法
2-1. 変数の宣言とスコープ
JavaScriptでは、変数を次の3つのキーワードで宣言できます。
let
:ブロックスコープの変数
let count = 5;
count = count + 1; // OK
const
:再代入不可の定数
const name = "Yamazaki";
// name = "Tanaka"; // エラー!
var
:昔の書き方(関数スコープ)→ 非推奨
var oldVar = 10; // 古い書き方、基本使わない
グローバルスコープとローカルスコープ
グローバルスコープ
関数やブロックの外で宣言された変数は、どこからでもアクセスできるグローバルスコープになります。特にconst
やlet
でグローバルに宣言した変数は、スクリプト全体で使えます。
const globalVar = "全体で使える";
function show() {
console.log(globalVar); // 参照できる
}
ローカルスコープ(関数スコープ・ブロックスコープ)
関数の中や、if
やfor
などのブロック内で宣言された変数は、その内部でのみ有効です。他からは参照できません。
function example() {
let localVar = "ここだけ有効";
console.log(localVar);
}
// console.log(localVar); // エラー:外からは見えない
2-2. データ型の基本
主なプリミティブ型
型名 | 例 | 備考 |
---|---|---|
数値(Number) | 42 , 3.14 | 整数・小数の区別なし |
文字列(String) | "Hello" , 'Hi' , `ようこそ` | シングル・ダブル・バッククォート |
真偽値(Boolean) | true , false | 条件分岐でよく使う |
未定義(undefined) | 未代入の変数 | let x; console.log(x); // undefined |
null | 値が存在しないことを明示 | let user = null; |
let age = 25;
let name = "Yamazaki";
let isMember = true;
2-3. 演算子
算術演算子
let a = 5 + 2; // 7
let b = 5 - 2; // 3
let c = 5 * 2; // 10
let d = 5 / 2; // 2.5(Javaとの違い)
let e = 5 % 2; // 1(剰余)
比較演算子
3 == "3" // true(型が違ってもOK)
3 === "3" // false(型も比較 → これを推奨!)
5 !== 4 // true
論理演算子
true && false // AND(→ false)
true || false // OR(→ true)
!true // NOT(→ false)
2-4. テンプレート文字列
JavaScriptでは、変数を文字列に埋め込むとき、バッククォート `
を使ったテンプレートリテラルが便利です。
let name = "Yamazaki";
let age = 30;
let message = `名前は${name}、年齢は${age}歳です。`;
console.log(message);
// → 名前はYamazaki、年齢は30歳です。
第3章 制御構文と関数
3-1. 条件分岐(if / else if / else)
Javaと同様に、条件に応じた処理を分けることができます。
let score = 85;
if (score >= 90) {
console.log("とても良くできました!");
} else if (score >= 70) {
console.log("よくできました!");
} else {
console.log("がんばりましょう!");
}
条件式のかっこ
( )
やブロック{ }
の書き方はJavaと同じです。
3-2. switch文
複数の分岐条件を判定するときに使います。
let fruit = "apple";
switch (fruit) {
case "apple":
console.log("リンゴです");
break;
case "banana":
console.log("バナナです");
break;
default:
console.log("その他の果物です");
}
break
を忘れると下まで実行されてしまうので注意!
3-3. 繰り返し処理(for / while)
for文
for (let i = 0; i < 5; i++) {
console.log(`iは${i}`);
}
Javaとほぼ同じ構文です。
while文
let count = 0;
while (count < 3) {
console.log(count);
count++;
}
3-4. for...of文(配列の繰り返し)
JavaScriptには、配列の要素を簡単に取り出す構文があります。
const fruits = ["apple", "banana", "orange"];
for (const fruit of fruits) {
console.log(fruit);
}
Javaの「拡張for文」に似た感覚で使えます。
3-5. 関数の定義と呼び出し
通常の関数定義(function宣言)
function greet(name) {
return `こんにちは、${name}さん!`;
}
console.log(greet("Imai")); // → こんにちは、Imaiさん!
関数式(変数に代入:無名関数)
const greet = function(name) {
return `こんにちは、 ${name}さん`;
};
アロー関数(ES6以降の書き方:無名関数)
const greet = (name) => {
return `こんにちは、 ${name}さん`;
};
1行だけなら波かっこ・return
も省略可能:
const greet = name => `こんにちは、${name}さん`;
3-6. スコープ(変数の有効範囲)
JavaScriptでは関数の内外でスコープ(見える範囲)が異なります。
let x = 10;
function sample() {
let y = 5;
console.log(x); // 10(外の変数は見える)
}
console.log(y); // エラー!(関数内の変数は外から見えない)
let
やconst
はブロックスコープ。Javaと似た感覚で扱えます。
第4章 配列とオブジェクトの基本
4-1. 配列(Array)とは?
配列は、複数の値を順番に格納するためのデータ構造です。JavaでいえばArrayListに似ています。JavaScriptでは、次のように定義します。
const fruits = ["apple", "banana", "orange"];
console.log(fruits[0]); // apple(0番目)
- 添字(インデックス)は 0 から始まります(Javaと同じ)
- 異なる型の要素も混在できます(ただしあまり推奨されません)
const mixed = [1, "hello", true]; // 数値、文字列、真偽値
4-2. 配列の主な操作
要素の追加・削除
let animals = ["dog", "cat"];
animals.push("rabbit"); // 末尾に追加
animals.pop(); // 末尾を削除
animals.unshift("lion"); // 先頭に追加
animals.shift(); // 先頭を削除
繰り返し処理(forEach, map)
const numbers = [1, 2, 3];
numbers.forEach(num => {
console.log(num * 2); // 2, 4, 6
});
const doubled = numbers.map(num => num * 2); // [2, 4, 6]
参考アロー関数を使わない forEach
const numbers = [1, 2, 3];
numbers.forEach(function(num) {
console.log(num * 2); // 2, 4, 6
});
参考アロー関数を使わない map
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(doubled); // [2, 4, 6]
配列の長さ、検索、結合など
const fruits = ["apple", "banana"];
console.log(fruits.length); // 配列の長さ(2)
console.log(fruits.includes("banana")); // true
console.log(fruits.join(", ")); // "apple, banana"
4-3. オブジェクト(Object)とは?
オブジェクトは、名前(キー)と値のセットを持つデータ構造です。JavaのMap<String, Object>
のようなイメージです。
const user = {
name: "Imai",
age: 30,
isMember: true
};
console.log(user.name); // Imai
console.log(user["age"]); // 30(どちらの書き方も可)
4-4. オブジェクトの操作
プロパティの追加・更新・削除
user.email = "Yamazaki@example.com"; // 追加
user.age = 31; // 更新
delete user.isMember; // 削除
オブジェクトのループ処理(for...in)
for (const key in user) {
console.log(`${key}: ${user[key]}`);
}
4-5. 配列×オブジェクトの組み合わせ
現実のWeb開発では、オブジェクトの配列を扱う場面が多いです。例えばユーザー一覧、商品一覧など。
const users = [
{ name: "Imai", age: 30 },
{ name: "Matsuda", age: 25 },
];
users.forEach(user => {
console.log(`${user.name}(${user.age}歳)`);
});
4-6. オブジェクトの分割代入(Destructuring Assignment)
オブジェクトの中から特定のプロパティを変数として取り出す簡潔な書き方が「分割代入」です。
const user = {
name: "Imai",
age: 30,
isMember: true
};
// 通常の書き方
const name = user.name;
const age = user.age;
// 分割代入を使うとより簡潔に書ける
const { name, age } = user;
console.log(name); // "Imai"
console.log(age); // 30
また、プロパティ名を変えたい場合は「:(コロン)」を使って別名をつけることもできます。
const { name: userName, age: userAge } = user;
console.log(userName); // "Imai"
console.log(userAge); // 30
よくある用途
- 関数の引数で使って、受け取るプロパティだけ抜き出す
- 複雑なデータ構造でも、コードがすっきりして読みやすくなる
function showUser({ name, age }) {
console.log(`${name}さんは${age}歳です`);
}
showUser(user); // Imaiさんは30歳です
次章は、Spring Boot + Thymeleafの画面にJavaScriptを組み込むために不可欠な「DOM(Document Object Model)」を解説します。
第5章 DOM操作の基礎
DOMってなに?
まず、「DOMって何?」というところからはじめましょう。
DOM(Document Object Model)は、Webページをオブジェクトとして扱う仕組みのことです。
たとえば、次のようなHTMLがあったとします。
<body>
<h1 id="title">Hello</h1>
</body>
これをJavaScriptで操作するには、「document
」というオブジェクトを使って、まるで「木の枝をたどるように」要素にアクセスします。
代表的なDOM組み込みオブジェクト一覧
オブジェクト名 | 役割・用途 |
---|---|
window | ブラウザのウィンドウ全体を表す |
document | Webページ(HTMLドキュメント)全体を表す |
Element | HTMLの要素(タグ)を表す |
Node | DOMツリーのノードを表す(テキストなども含む) |
NodeList | ノードの一覧(配列っぽいけど配列ではない) |
HTMLCollection | HTML要素のコレクション(これも配列ではない) |
Event | イベントオブジェクト(クリック・キーボードなど) |
HTMLElement | 特定のHTML要素型の親クラス(例:HTMLDivElement ) |
それぞれを詳しく解説!
1. windowオブジェクト
JavaScriptの最上位オブジェクトで、ブラウザのタブそのものを指します。
console.log(window.innerWidth); // ウィンドウの幅
ちなみに、
alert()
やsetTimeout()
などもwindow.alert()
の省略形です!
2. documentオブジェクト
window.document
は、Webページの内容そのもの(HTMLドキュメント)を指します。
document.getElementById("title").textContent = "こんにちは!";
ページ内の要素にアクセスする入り口です!
3. Elementオブジェクト
これは、HTMLのタグ1つ1つを表すオブジェクトです。
let el = document.querySelector("h1");
el.style.color = "red";
Element
はHTMLElement
の親クラスにあたります。
4. Nodeオブジェクト
DOMの構造は「ノード(節)」として表現されます。
<div>
→ 要素ノード"こんにちは"
→ テキストノード
というように、すべての要素や文字列が「ノード」として扱われます。
let node = document.getElementById("title").childNodes[0];
Node
はElement
よりも広い概念です。
5. NodeListとHTMLCollectionの違い
どちらも複数の要素を格納した「配列っぽいもの」ですが、違いに注意!
特徴 | NodeList | HTMLCollection |
---|---|---|
作られる関数例 | querySelectorAll() | getElementsByTagName() など |
更新される? | いいえ(静的) | はい(動的) |
forEach使える? | 使える(モダンブラウザ) | 使えない |
6. Eventオブジェクト
クリックやキーボード入力など、イベントの情報を保持するオブジェクトです。
document.addEventListener("click", function(event) {
console.log(event.target); // クリックされた要素
});
event
という引数は、イベントに関するすべての情報を含んでいます。
7. HTMLElementとそのサブクラスたち
HTMLElement
は、すべてのHTML要素の共通の型であり、さらに具体的な要素ごとに次のようなクラスがあります。
クラス名 | 対応するHTML要素 |
---|---|
HTMLDivElement | <div> |
HTMLInputElement | <input> |
HTMLButtonElement | <button> |
let btn = document.querySelector("button");
console.log(btn instanceof HTMLButtonElement); // true
DOMの階層構造:図でイメージしよう
window
└─ document
└─ <html>
└─ <body>
├─ <h1>
│ └─ TextNode ("Hello")
└─ <p>
└─ TextNode ("Welcome")
このように、ツリー構造(木構造)になっているのがDOMの特徴です。
よくある操作例:実践で使える!
要素を取得する
document.getElementById("title")
document.querySelector(".item")
要素を作る・追加する
let p = document.createElement("p");
p.textContent = "新しい段落";
document.body.appendChild(p);
クラスやスタイルを変更する
el.classList.add("active");
el.style.backgroundColor = "blue";
例:以下のようなHTMLがあるとします
<h1 id="title">こんにちは</h1>
→ これはJavaScriptから次のようにアクセスできます:
const heading = document.getElementById("title");
heading.textContent = "ようこそ!";
5-2. 要素の取得方法
DOM操作の第一歩は、対象となるHTML要素を取得することです。
document.getElementById(id)
id
が付いた要素を1つ取得します(最速でシンプル)
<p id="message">Hello</p>
const msg = document.getElementById("message");
document.querySelector(cssセレクタ)
- CSSセレクタで要素を1つ取得します(汎用的)
<p class="text">こんにちは</p>
const text = document.querySelector(".text");
document.querySelectorAll(cssセレクタ)
- 複数の要素を一括で取得します(配列風オブジェクトが返る)
<ul>
<li class="item">A</li>
<li class="item">B</li>
</ul>
const items = document.querySelectorAll(".item");
items.forEach(item => console.log(item.textContent));
5-3. テキストやHTMLの変更
textContent
:テキストのみ書き換える
heading.textContent = "ようこそ!";
innerHTML
:HTMLごと差し替え(タグも書き換える)
div.innerHTML = "<strong>太字で表示</strong>";
innerHTML
は柔軟ですが、ユーザー入力を直接代入するとXSS(セキュリティ問題)になりやすいため注意が必要です。
5-4. 属性やクラスの操作
属性を変更する:setAttribute
, getAttribute
const link = document.querySelector("a");
link.setAttribute("href", "https://example.com");
クラスを追加・削除・切り替え:classList
element.classList.add("active");
element.classList.remove("hidden");
element.classList.toggle("selected");
5-5. 要素の追加・削除
要素を作成して追加する
const ul = document.querySelector("ul");
const li = document.createElement("li");
li.textContent = "新しい項目";
ul.appendChild(li);
要素を削除する
ul.removeChild(li); // 親から子を削除
または、直接 .remove()
で削除することも可能(新しめの方法):
li.remove();
5-6. Spring Boot × DOM操作の注意点
Spring Boot + Thymeleafでは、テンプレートで生成されるHTMLにJavaScriptがアクセスする場合:
- JavaScriptの読み込みはHTMLの末尾に配置(
</body>
直前)するのが原則 - DOMがまだ読み込まれていないと、要素が
null
になるので注意!
<!-- OKな配置例 -->
<script src="/js/main.js"></script>
</body>
</html>
もしくは
DOMContentLoaded
イベントを使って、「ページの読み込み完了後」に処理を実行する方法もあります(次章で詳しく扱います)。
第6章 イベント処理の基本
6-1. イベントとは?
イベントとは、ユーザーの操作(クリック、入力、スクロールなど)に対してブラウザが発生させる「出来事」です。
JavaScriptではこのイベントに反応(リッスン)して、任意の処理を実行できます。
代表的なイベントの種類
イベント名 | 発生タイミング |
---|---|
click | 要素がクリックされたとき |
input | 入力欄の内容が変更されたとき |
submit | フォームが送信されたとき |
change | セレクトボックスやチェックボックスが変更されたとき |
DOMContentLoaded | ページのHTML読み込み完了時 |
6-2. addEventListener
を使ったイベント登録
JavaScriptでは、addEventListener
を使ってイベントを設定するのが基本です。
例:ボタンがクリックされたらメッセージを表示
<button id="myBtn">クリックしてね</button>
const btn = document.getElementById("myBtn");
btn.addEventListener("click", () => {
alert("ボタンがクリックされました!");
});
- 第1引数:イベント名(文字列)
- 第2引数:実行する関数(イベントハンドラ)
6-3. event
オブジェクトで詳細を取得
イベントハンドラの関数には、event
オブジェクトが自動で渡されます。
btn.addEventListener("click", (event) => {
console.log(event.target); // イベントが発生した要素
});
これを使えば、複数のボタンに1つの関数で対応することも可能です。
6-4. フォーム送信イベントと preventDefault()
フォーム送信(submit
イベント)は、通常だとページ遷移やリロードが発生します。
JavaScriptで制御したい場合は、preventDefault()
を使ってそれを止めます。
例:送信ボタンを押したらアラートを表示し、ページ遷移を防ぐ
<form id="form">
<input type="text" name="username" />
<button type="submit">送信</button>
</form>
const form = document.getElementById("form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // デフォルトの動作(送信)をキャンセル
alert("フォームが送信されました!");
});
6-5. 入力イベントでリアルタイムに反応する
input
イベント:テキスト入力のたびに呼び出される
<input id="nameInput" />
<p id="preview">こんにちは!</p>
const input = document.getElementById("nameInput");
const preview = document.getElementById("preview");
input.addEventListener("input", () => {
preview.textContent = `こんにちは、${input.value}さん!`;
});
フォームの内容をリアルタイムに画面に反映させる例です。
6-6. よくあるパターン:ループ + イベント
複数の要素にイベントをまとめて設定することもよくあります。
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
</ul>
const items = document.querySelectorAll(".item");
items.forEach(item => {
item.addEventListener("click", () => {
item.classList.toggle("selected");
});
});
第7章 実践!Spring Bootアプリと連携するJavaScript
7-1. Spring BootとJavaScriptの関係
Spring Bootでは、@Controller
でHTMLテンプレート(Thymeleaf)を返し、そのHTMLに対してJavaScriptを使って動的な動きを付け加えるのが一般的です。
【例】
Controller → Thymeleaf → HTML表示 → JavaScriptでDOM操作やイベント処理
JavaScriptの主な役割:
- 入力チェック(バリデーション)
- フォームの補助入力やリアルタイム表示
- 表示の切り替え(例:モーダル、エラーメッセージ)
- ユーザーの操作ログの取得・確認
7-2. HTML要素とJavaScriptの連携方法
JavaScriptから要素を操作するには、id
やclass
が重要な目印となります。Thymeleafとの組み合わせでは、以下のように書くことが多いです。
Thymeleafの中でid/classを使う
<input type="text" th:id="'nameInput'" th:value="${user.name}">
<p id="namePreview">ようこそ!</p>
const input = document.getElementById("nameInput");
const preview = document.getElementById("namePreview");
input.addEventListener("input", () => {
preview.textContent = `こんにちは、${input.value}さん!`;
});
th:id
を使うと Thymeleaf によってHTMLが生成されたあとでも JavaScript で操作可能になります。
7-3. 表示の切り替え(エラー表示、詳細表示など)
classの追加/削除で表示切り替え
<div id="errorBox" class="hidden">エラーがあります</div>
.hidden { display: none; }
const errorBox = document.getElementById("errorBox");
errorBox.classList.remove("hidden"); // 表示する
クラスを使った切り替えは、見た目を保ったまま制御できるので非常に実用的です。
7-4. 確認ダイアログ(削除ボタンの確認)
Spring Bootアプリでよくあるのが「削除ボタンの押し間違い防止」です。
<form th:action="@{/delete}" method="post" onsubmit="return confirmDelete();">
<button type="submit">削除</button>
</form>
function confirmDelete() {
return confirm("本当に削除してよろしいですか?");
}
confirm()
はシンプルな組み込みダイアログです。
7-5. 動的リストの追加・削除
JavaScriptで動的に要素を追加する例
<ul id="todoList"></ul>
<input type="text" id="todoInput">
<button id="addBtn">追加</button>
const list = document.getElementById("todoList");
const input = document.getElementById("todoInput");
const addBtn = document.getElementById("addBtn");
addBtn.addEventListener("click", () => {
const text = input.value;
if (text.trim() !== "") {
const li = document.createElement("li");
li.textContent = text;
list.appendChild(li);
input.value = ""; // 入力欄をリセット
}
});
このように、Spring Bootから表示された画面でも、ユーザーの入力内容を元に動的なリスト表示が実現できます。
7-6. 実務で使えるちょっとしたテクニック集
ページ読み込み後に処理を実行する方法
document.addEventListener("DOMContentLoaded", () => {
console.log("ページが読み込まれました");
});
これは、要素を操作する前にDOMの読み込みを保証する安全な方法です。
data-属性
を活用したデータ埋め込み
Thymeleafでは、data-属性
を使ってサーバーからのデータをHTMLに埋め込んでおき、JavaScriptで拾うという手法もよく使われます。
<button class="deleteBtn" th:data-id="${item.id}">削除</button>
const btns = document.querySelectorAll(".deleteBtn");
btns.forEach(btn => {
btn.addEventListener("click", () => {
const id = btn.dataset.id;
console.log(`削除対象のID: ${id}`);
});
});
JavaScript研修、お疲れさまでした。
HTML/CSSとJavaの基礎を土台に、JavaScriptの文法からDOM操作、イベント処理、そしてSpring Bootとの連携までを駆け抜けた皆さんの努力は、これからの現場で確かな力になります。大切なのは、知識を「知っている」だけでなく「使ってみる」こと。疑問にぶつかったときこそ学びのチャンスです。これからも実践を重ね、チームやユーザーのために“動く画面”を作れるエンジニアとして、ますます活躍されることを心より願っています。