[JavaScript] 指定ページのみで発火させるスクリプトの構成
3 min read
使用する想定状況
EC サイトにおける、商品一覧・商品詳細・カートページでそれぞれ固有の処理を走らせたい。
ただし、商品一覧(item-list.js)・商品詳細(item-detail.js)・カートページ(cart.js)を言ったように各ファイルを用意するのではなく、1 つの index.js に集約してページごとに実行処理を分岐させる。
準備
ページを特定できるよう属性を付与する
各ページに特定できるような属性を付けてスクリプト側から区別できるようにする(ここでは data-page
)
<!-- 商品一覧 -->
<body data-page="itemList">
<!-- イカした一覧ページ -->
</body>
<!-- 商品詳細 -->
<body data-page="itemDetail">
<!-- イカした詳細ページ -->
</body>
<!-- カート -->
<body data-page="cart">
<!-- イカしたカートページ -->
</body>
ハンドリングするスクリプト
export default eventLoader = (functions) => {
fire(functions, "common");
// ページ名を取得
const pageName = document.body.dataset.page;
if (!pageName) return;
// ページ固有のJSを実行
fire(functions, pageName);
};
const fire = (functions, pageName) => {
// ページ名とイベントが一致しているかチェック
const defaultFunction = "init";
const hasFunction =
functions[pageName] &&
typeof functions[pageName][defaultFunction] === "function";
if (!hasFunction) return;
// 一致したdefault eventを実行
try {
functions[pageName][defaultFunction]();
} catch (e) {
console.error(e);
}
};
使用方法
eventLoader を読み込む
import eventLoader from "./eventLoader";
import common from "./common";
import itemList from "./item-list";
import itemDetail from "./item-detail";
import cartPage from "./cart";
const functions = {
// 共通
common,
// ページ
itemList,
itemDetail,
cart: cartPage,
};
document.addEventListener("DOMContentLoaded", eventLoader(functions), false);
eventLoader
の引数に渡すObject
:
key | value |
---|---|
data-page と一致する名称 | data-page で実行させたいモジュール |
実行用モジュール
export default {
init() {
// SUGOI SYORI
},
};
Object
内にinit
関数を用意する(Facade な役割)
※こちらは前述のeventLoader
の実装仕様に依るので、そちらの処理を書き換えることで当然クラスを実行するかたちにもできる
大まかな仕様
DOMContentLoaded
時にeventLoader
を実行eventLoader
には各種モジュールを定義したObject
を渡す
eventLoader
:body
要素のdata-page
を取得するdata-page
の文字列にマッチしたモジュール内のinit()
を実行する