読み込み中...

JavaScriptで拡張子を活用する方法12選!初心者でも簡単にできる方法

初心者向けJavaScript拡張子活用方法 JS
この記事は約26分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

JavaScriptの拡張子を理解すると、HTMLから外部ファイルを読み込み、画面操作や入力処理を分けて管理できます。その分離によって、初心者でもindex.htmlmain.jsの役割を切り分けやすくなり、サンプルコードを小さく試す方法も選びやすくなります。

その一方で、.jsを置くだけではブラウザに読み込まれません。<script>の位置、srcのパス、defertype="module"の違いを押さえることが、拡張子まわりの注意点を減らす近道になるでしょう。

動作確認環境
  • HTML Living Standard / ECMAScript 2024 の基本構文
  • Google Chrome 126、Firefox 127、Safari 17 系の標準ブラウザ機能
  • 外部ライブラリなし。jQuery例のみ CDN 読み込みの注意点として扱います
📖 この記事で学べること
  • JavaScriptの拡張子.js.mjsの違い
  • HTMLから外部JavaScriptファイルを読む方法
  • 初心者が間違えやすいパス、読み込み順、DOM操作の注意点
  • 画像スライダーやアコーディオンなどのサンプルコードの考え方
  • 読み込み順やUI部品をカスタマイズするときの判断基準

JavaScript拡張子とは

JavaScript拡張子とは、JavaScriptのソースコードを保存するファイル名の末尾を指します。一般的な拡張子は.jsで、ブラウザはHTMLの<script>要素からそのファイルを取得し、記述された処理を実行対象として扱います。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script src="main.js" defer></script>
</head>
<body>
  <p id="message"></p>
</body>
</html>

結果: 期待される表示は、同じ階層にあるmain.jsがHTML解析後に読み込まれ、message要素をJavaScriptから操作できる状態です。

これを支える仕様は、HTML側では<script>要素、JavaScript側ではECMAScriptの構文です。公式ドキュメントによれば、MDNのscript要素リファレンスではsrcdeferasynctypeなどの属性が整理されています。

そのため、拡張子だけを覚えるより、HTMLがどのタイミングでJavaScriptファイルを取得するかまで合わせて理解するのが現実的です。.jsはファイルの種類を示す目印であり、読み込み方法は<script src="...">側で決まります。

一般に、通常のスクリプトは.js、ES Modulesとして分けたいファイルは.mjstype="module"を使う構成が見られますし、ここがポイントです。MDNのJavaScriptモジュールガイドでも、モジュールを使う場合の読み込み方とファイル分割の考え方が説明されているのが基本です。

💡 Tips: 小規模なページではmain.jsに処理を集め、規模が大きくなったらimportexportで分ける方法が扱いやすいでしょう。
分類対象主な役割注意点初心者向けの判断
基本.js通常のJavaScriptファイルHTMLから読まないと動かない最初に使う拡張子
モジュール.mjsES Modulesを明示MIME設定に注意学習後でよい
HTML<script>JavaScriptを読み込む閉じタグが必要必ず覚える
属性src外部ファイルの場所相対パスの誤りが多い同階層から確認
属性deferHTML解析後に実行インラインには使えないDOM操作向け
属性async取得後すぐ実行順序依存に不向き解析タグ向け
属性type="module"モジュールとして読むローカル直開きに注意サーバー経由
DOMdocumentページ全体の入口読み込み前参照に注意deferと併用
DOMquerySelector()CSSセレクタで取得最初の1件だけ返す汎用的
DOMquerySelectorAll()複数要素を取得NodeListを返す一覧操作
DOMgetElementById()IDで取得ID重複を避ける単独要素
DOMtextContentテキストを書き換えるHTML解釈なし安全寄り
DOMinnerHTMLHTML文字列を反映入力値直挿入は危険必要時だけ
イベントaddEventListener()イベント処理を登録関数参照に注意onclickより整理
イベントclickクリック操作キーボードも考えるボタン向け
イベントinput入力中の値変化頻度が高いフォーム向け
配列forEach()要素を順に処理途中終了に不向き一覧更新
配列map()新しい配列を作る副作用中心にしない変換向け
時間setTimeout()遅延実行繰り返しは再呼び出し単発向け
時間setInterval()一定間隔で実行停止にはclearが必要タイマー向け
CSSdisplay表示状態を切り替えるレイアウトが変わるメニュー向け
CSSopacity透明度を変える領域は残るフェード向け
CSStransition変化を滑らかにする対象を意識演出向け
CSSposition配置基準を作る親子関係に注意モーダル向け
CSSz-index重なり順を決めるpositionと関係前面表示
フォームvalue入力値を読む文字列として扱う型変換
フォームsubmit送信処理ページ遷移に注意preventDefault
安全rel="noopener"別タブ参照を抑える外部リンクで忘れやすいtarget時に付ける
構成assets/js/ファイルを整理パス変更が必要中規模向け
構成DOMContentLoadedDOM構築後に処理deferと重複しやすい位置で判断

この早見表では、拡張子そのものだけでなく、HTML、DOM、CSS、イベント処理まで並べています。初心者がつまずきやすいのは、.jsのファイル名よりもsrcの相対パス、DOMの読み込み順、表示切り替え用CSSの不足であるためです。

⚠️ 注意: 古い直接書き込みAPIを通常の画面更新に使う方法は避けます。現在のDOM操作では、textContentappend()replaceChildren()などを使う構成が扱いやすいです。

JavaScript拡張子の使い方

JavaScript拡張子の使い方は、HTMLに読み込ませる処理と、読み込まれたファイル内でDOMやイベントを扱う処理に分かれますが、これは押さえたい点です。その分け方を守ると、サンプルコードのどこがHTMLで、どこがJavaScriptなのかを追いやすくなるでしょう。

具体的には、JavaScriptイベント徹底解説!30個の使い方と応用例のようなイベント処理も、外部ファイルへ分けると見通しがよくなります。イベントの種類が増えるほど、onclick属性に直接書くよりaddEventListener()でまとめる方法が読みやすいです。

サンプルコード1:外部ファイルの読み込み

基本的に、HTMLと同じ階層にあるapp.jssrc="app.js"で読めます。この方法では、拡張子.jsを持つファイルをHTMLから明示的に参照するのが基本です。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script src="app.js" defer></script>
</head>
<body>
  <h1 id="title">読み込み前</h1>
</body>
</html>

結果: 期待される表示は、app.js側の処理からtitle要素へアクセスできる状態です。deferにより、HTML解析の完了後に外部ファイルの処理が走ります。

その注意点として、app.jsjs/app.jsに移動した場合はsrc="js/app.js"へ変える必要があります。初心者はファイル名の大文字小文字やフォルダ階層を見落としやすいため、開発者ツールで404の有無を確認すると整理しやすいです。

サンプルコード2:テキストを書き換える

このサンプルコードでは、textContentを使ってHTML要素の文字列を変えますし、これが一つの目安です。ユーザー入力をそのまま画面へ出す場面では、innerHTMLよりtextContentのほうが安全寄りだと覚えるとよいでしょう。

const message = document.getElementById("message");
message.textContent = "Hello, JavaScript!";

結果: 期待される出力は、id="message"の要素内に「Hello, JavaScript!」というテキストが入る状態です。HTMLタグ文字列は解釈されず、文字として扱われます。

これに対応するHTMLには、<p id="message"></p>のような受け皿を用意します。その要素が存在しない場合、getElementById()nullを返すため、読み込み順かID名のどちらかに誤りがあると考えられますが、覚えておくと役立つでしょう。

サンプルコード3:外部ライブラリを読む

一方、CDNから外部ライブラリを読む方法もあるのが目安です。ただし、外部URLへの依存はネットワークや提供元の変更に影響されるため、バージョン固定や代替策を含めて判断します。

<script src="https://code.jquery.com/jquery-3.7.1.min.js"
        integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
        crossorigin="anonymous"></script>
<script src="main.js" defer></script>

結果: 期待される出力は、jQuery本体を読み込んだ後にmain.jsを利用できる状態です。integritycrossoriginは、CDN利用時の検証に関係します。

ただし、現在の標準DOM APIだけで実装できる処理も多くあります。たとえばforEach・mapの使い分けを理解すると、一覧要素の更新はquerySelectorAll()forEach()で扱える場合があるのが目安です。

サンプルコード4:フォーム入力を受け取る

フォーム入力を扱う場合は、input要素のvalueを読み取り、結果表示用の要素へ反映するのがポイントです。この方法では、HTMLの構造とJavaScriptの処理が対応します。

<input type="text" id="nameInput" autocomplete="name">
<button id="showButton" type="button">表示</button>
<p id="output"></p>
<script src="form.js" defer></script>

結果: 期待される表示は、入力欄、表示ボタン、出力欄が並ぶ状態です。実際の文字反映は、次のform.jsでイベントを登録したあとに起こりますし、ここを基本と考えるとよいでしょう。

このとき、buttontype="button"を付けておくと、フォーム内に置いた場合でも意図しない送信を避けやすくなります。送信処理まで扱うなら、submitイベントとevent.preventDefault()を組み合わせます。

const input = document.getElementById("nameInput");
const button = document.getElementById("showButton");
const output = document.getElementById("output");
button.addEventListener("click", () => {
  output.textContent = `入力値: ${input.value}`;
});

結果: 期待される出力は、ボタンを押したときにoutputへ「入力値: …」が入る状態です。入力値は文字列として扱われますし、ここがポイントです。

JavaScript拡張子の応用例

JavaScript拡張子を使ったファイル分割に慣れたら、UI部品ごとにslider.jsaccordion.jsmodal.jsのような名前を付けると管理しやすくなります。その名前付けは機能単位を示すため、注意点やカスタマイズ範囲も見つけやすいです。

実際、JavaScriptにおけるイベントハンドラの実践例と同じように、UIの多くはイベントを受けてクラスや属性を変える構造です。DOMを直接書き換える量を抑え、CSSクラスで見た目を制御すると、JavaScript側の責務が明確になります。

サンプルコード5:画像スライダー

画像スライダーでは、現在の画像だけにactiveクラスを付け、CSSで表示を切り替えますが、これは押さえたい点です。この方法なら、表示デザインのカスタマイズはCSS側、順番の制御はJavaScript側に分けられますし、ここがポイントです。

<div class="slider">
  <img src="image1.jpg" alt="朝の風景" class="slide active">
  <img src="image2.jpg" alt="昼の風景" class="slide">
  <img src="image3.jpg" alt="夜の風景" class="slide">
</div>
<script src="slider.js" defer></script>

結果: 期待される表示は、activeが付いた1枚目の画像だけが初期表示される状態です。altは画像が読めない場合や支援技術向けの説明になります。

const slides = document.querySelectorAll(".slide");
let current = 0;
setInterval(() => {
  slides[current].classList.remove("active");
  current = (current + 1) % slides.length;
  slides[current].classList.add("active");
}, 3000);

結果: 期待される出力は、3秒ごとにactiveクラスが次の画像へ移る動きです。CSS側で.slideを非表示、.slide.activeを表示にしておく必要があります。

サンプルコード6:アコーディオンメニュー

アコーディオンは、見出しボタンの直後にある内容領域を開閉するUIです。nextElementSiblingを使うと、ボタンと内容の対応関係をHTMLの並びで表せます。

<div class="accordion">
  <button class="accordion-toggle" type="button" aria-expanded="false">基本設定</button>
  <div class="accordion-content" hidden>設定内容を表示するのがポイントです。</div>
</div>
<script src="accordion.js" defer></script>

結果: 期待される表示は、ボタンと非表示の内容領域が用意された状態です。hidden属性により、初期状態では内容が画面に出ません。

document.querySelectorAll(".accordion-toggle").forEach((button) => {
  button.addEventListener("click", () => {
    const panel = button.nextElementSibling;
    const isOpen = button.getAttribute("aria-expanded") === "true";
    button.setAttribute("aria-expanded", String(!isOpen));
    panel.hidden = isOpen;
  });
});

結果: 期待される出力は、クリックごとにaria-expandedhiddenが切り替わる状態です。見た目だけでなく状態もHTML属性に残ります。

サンプルコード7:モーダルウィンドウ

モーダルでは、開くボタン、閉じるボタン、重ねる領域を用意します。初心者がつまずきやすいのは、表示切り替えだけでなく、背景クリックなどの閉じ方を後から足し忘れる点です。

<button id="openModal" type="button">開く</button>
<div id="modal" class="modal" hidden>
  <div class="modal-content" role="dialog" aria-modal="true">
    <button id="closeModal" type="button">閉じる</button>
    <p>モーダルの内容です。</p>
  </div>
</div>
<script src="modal.js" defer></script>

結果: 期待される表示は、開くボタンと、初期状態では非表示のモーダル領域です。role="dialog"aria-modal="true"で役割を示します。

const modal = document.getElementById("modal");
const openButton = document.getElementById("openModal");
const closeButton = document.getElementById("closeModal");
openButton.addEventListener("click", () => { modal.hidden = false; });
closeButton.addEventListener("click", () => { modal.hidden = true; });
modal.addEventListener("click", (event) => {
  if (event.target === modal) modal.hidden = true;
});

結果: 期待される出力は、開くボタンでhiddenが外れ、閉じるボタンまたは背景クリックで再び非表示になる動きです。

サンプルコード8:ドロップダウンメニュー

ドロップダウンメニューは、ボタンでメニューを開き、外側のクリックで閉じる構成にすると使いやすくなります。特に押さえたいのは、クリックされた対象をclosest()でたどる方法です。

<div class="dropdown">
  <button class="dropbtn" type="button" aria-expanded="false">メニュー</button>
  <div class="dropdown-content" hidden>
    <a href="/web/3446/">forEachの記事</a>
    <a href="/web/3597/">カレンダーの記事</a>
  </div>
</div>
<script src="dropdown.js" defer></script>

結果: 期待される表示は、メニューボタンと非表示のリンク領域です。内部リンクを置く場合も、開閉状態はhiddenaria-expandedで管理できます。

const dropdown = document.querySelector(".dropdown");
const dropButton = dropdown.querySelector(".dropbtn");
const menu = dropdown.querySelector(".dropdown-content");
document.addEventListener("click", (event) => {
  const inside = event.target.closest(".dropdown");
  const shouldOpen = inside && event.target === dropButton && menu.hidden;
  menu.hidden = !shouldOpen;
  dropButton.setAttribute("aria-expanded", String(shouldOpen));
});

結果: 期待される出力は、ボタンを押すとメニューが開き、ドロップダウン外を押すと閉じる動きです。複数メニューに広げる場合は、各.dropdownごとに処理を分けます。

サンプルコード9:スクロールアニメーション

スクロールアニメーションでは、要素が画面内に近づいたタイミングでクラスを追加します。軽い実装ならgetBoundingClientRect()で位置を読み、CSSで見た目を切り替えますし、これが一つの目安です。

<section class="fade-target">表示したい内容</section>
<section class="fade-target">別の内容</section>
<script src="scroll.js" defer></script>

結果: 期待される表示は、複数のfade-target要素がHTML上に並ぶ状態です。スクロール位置に応じた変化はJavaScriptとCSSで制御するのが一般的です。

const targets = document.querySelectorAll(".fade-target");
function updateFade() {
  const trigger = window.innerHeight * 0.85;
  targets.forEach((target) => {
    const top = target.getBoundingClientRect().top;
    target.classList.toggle("is-visible", top < trigger);
  });
}
window.addEventListener("scroll", updateFade);
updateFade();

結果: 期待される出力は、要素が画面高さの85%付近に入るとis-visibleクラスが付く動きです。初期表示分にも対応するため、最後にupdateFade()を呼びます。

サンプルコード10:カウントダウンタイマー

カウントダウンタイマーでは、終了日時と現在時刻の差を計算し、日・時・分・秒に分解します。期限が過ぎたあとの表示を決めておくことが注意点です。

<div id="timer" aria-live="polite">
  <span id="days">0</span>日
  <span id="hours">0</span>時間
  <span id="minutes">0</span>分
  <span id="seconds">0</span>秒
</div>
<script src="timer.js" defer></script>

結果: 期待される表示は、日・時・分・秒の表示枠が並ぶ状態です。aria-live="polite"により、更新領域であることを示します。

const endDate = new Date("2026-12-31T23:59:59+09:00");
const timerId = setInterval(() => {
  const remaining = Math.max(0, endDate - new Date());
  const totalSeconds = Math.floor(remaining / 1000);
  document.getElementById("days").textContent = Math.floor(totalSeconds / 86400);
  document.getElementById("hours").textContent = Math.floor(totalSeconds / 3600) % 24;
  document.getElementById("minutes").textContent = Math.floor(totalSeconds / 60) % 60;
  document.getElementById("seconds").textContent = totalSeconds % 60;
  if (remaining === 0) clearInterval(timerId);
}, 1000);

結果: 期待される出力は、2026年12月31日23時59分59秒(日本時間)までの残り時間が1秒ごとに更新される状態です。期限後は0で止まります。

ちなみに、ドロップダウンのリンク先を詳しく学ぶ導線としてJavaScriptのforEachでreturnを活用する6つのテクニックを組み込むと、一覧処理の理解にもつながります。リンクテキストは内容が分かる表現にして、#だけの仮リンクを残さないほうが管理しやすいです。

もっとも、スクロール対象が非常に多いページではIntersectionObserverを検討できるのが一般的です。スクロールイベントで毎回位置を計算する方法は理解しやすい一方、量が増えると処理回数が増えるためです。

カスタマイズ例

カスタマイズでは、動作の順番、見た目、ファイル構成を分けて考えると失敗を減らせますが、これは押さえたい点です。JavaScript拡張子のファイルを増やすほど、どのファイルがどのHTMLから読まれるか、依存関係がどこにあるかを整理する必要があります。

そのため、components/slider.jsutils/loadScript.jsのように役割を名前へ含める方法がよく使われますが、覚えておくと役立つでしょう。カレンダーのような部品を作る場合も、JavaScriptでカレンダーを作成!サンプルコード10選で簡単理解のように表示処理と日付計算を分けると見通しがよくなります。

サンプルコード11:読み込み順のカスタマイズ

外部ファイルに依存関係がある場合、Aを読んでからBを読む順番が必要になることがあるのが現実的です。簡単な方法として、Promiseを返すloadScript()を作ると、順序をコード上で表せますし、ここを基本と考えるとよいでしょう。

function loadScript(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = url;
    script.onload = resolve;
    script.onerror = reject;
    document.body.append(script);
  });
}
loadScript("file1.js")
  .then(() => loadScript("file2.js"))
  .then(() => console.log("読み込み完了"))
  .catch(() => console.error("読み込みに失敗しました"));

結果: 期待される出力は、file1.jsの読み込み後にfile2.jsが読み込まれ、成功時に「読み込み完了」がコンソールへ出る流れです。失敗時はエラー側の処理に進みます。

ただし、通常のページで多用すると読み込み順が追いにくくなります。依存関係が増える場合は、type="module"import、ビルドツールの導入を含めて設計するほうが現実的です。

サンプルコード12:画像スライダーのカスタマイズ

画像スライダーのカスタマイズでは、切り替え間隔、対象セレクタ、停止条件を引数にすると再利用しやすくなるのが現実的です。固定値を関数の外に出すことで、別ページでも同じ.jsを使い回せますし、これが一つの目安です。

function createSlider(selector, interval = 3000) {
  const root = document.querySelector(selector);
  if (!root) return;
  const slides = root.querySelectorAll(".slide");
  if (slides.length === 0) return;
  let index = 0;
  setInterval(() => {
    slides[index].classList.remove("active");
    index = (index + 1) % slides.length;
    slides[index].classList.add("active");
  }, interval);
}
createSlider(".main-slider", 2000);

結果: 期待される出力は、.main-slider内の.slideだけを対象に、2秒間隔でactiveが移動する動きです。対象がない場合は何もせず終了します。

この形にしておくと、createSlider(".sub-slider", 5000)のように別のスライダーへ応用できます。カスタマイズの幅を広げるほど、初期値、エラー時の動き、CSSクラス名の命名をそろえることが大切になると整理できると整理できます。

ℹ️ 補足: .jsファイルを分ける方法は学習しやすい一方、HTTPリクエスト数やキャッシュ設計にも関係します。制作規模が大きい場合は、モジュール分割とバンドルの役割を別々に考えます。

具体的には、イベントの戻り値や配列処理の流れを整理したい場合、forEachでreturnを扱う考え方を確認しておくと、UIの繰り返し処理で混乱しにくくなると理解できると理解できます。DOM一覧に対するforEach()は、戻り値ではなく副作用で要素を更新する処理に向いています。

まとめ

JavaScriptの拡張子は、単なるファイル名の末尾ではなく、HTMLから読み込む外部ファイル、DOM操作、イベント処理、CSSクラス制御を結び付ける入口です。.js<script>srcdeferの関係を理解すると、初心者でもサンプルコードの配置を判断しやすくなります。

そのうえで、拡張子.jsのファイルに処理を分ける方法は、画像スライダー、アコーディオン、モーダル、ドロップダウン、スクロール演出、タイマーなどに応用できると覚えるとよいでしょう。各部品では、JavaScriptが状態を変え、CSSが見た目を受け持つ構造にすると、注意点を切り分けやすいです。

ただし、コードの出力例は環境やHTML構造に左右されますが、覚えておくと役立つでしょう。期待される表示と異なる場合は、ファイルパス、要素ID、読み込み順、コンソールエラー、CSSクラス名の不一致を順に確認する方法が有効です。

カスタマイズを進めるときは、固定値を関数の引数に移し、存在しない要素へのアクセスを避け、外部リンクやCDNには安全属性を加えると整理できます。JavaScript拡張子の扱いを土台にして、ページの規模に合ったファイル構成へ育てていくのが実用的だと言えるでしょう。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。