【JavaScript入門】ページ全体の共通処理(common.jsとdateFormat.js)

 ここでは「みんなのつぶやき」アプリを支える 共通ユーティリティ である common.js日時フォーマッタ dateFormat.js の中身を詳しく解説します。
 どちらも「小さいけれど無いと不便」な機能を一箇所にまとめ、各画面モジュールから重複コードを排除する役割を担います。

フォルダ構成

まずはフォルダ構成を再確認しておきます。

node-js/
 ├─ app/
 │   ├─ index.html
 │   ├─ style.css
 │   └─ js/               ← JS モジュール群
 │        ├─ common.js       ← ここで作成
 │        ├─ storage.js
 │        ├─ imageArea.js
 │        ├─ imageEffects.js
 │        ├─ controlArea.js
 │        ├─ commentArea.js
 │        ├─ sendArea.js
 │        ├─ dateFormat.js   ← ここで作成
 │        └─ postListArea.js
 ├─ index.js               ← API/サーバ側
 ├─ upload_images/         ← 画像保存場所
 └─ post-dat.txt           ← 投稿データ(JSON など)

1.common.js

1.1. 役割

  • ページに共通する “お作法” を一括初期化
  • とくにモバイル端末でタップ連打しやすいよう ボタンから自動でフォーカスを外す

1.2. コメント付きソース

/* ---------------------------------------------------
   common.js
   ページ全体で共通して使う “小ネタ” をまとめたファイル
   - ここでは「ボタンクリック直後にフォーカスを外す」だけ
     しかし今後、共通関数を追加するハブとしても利用可
--------------------------------------------------- */

// DOM が完全に構築されたら一度だけ実行
window.addEventListener('DOMContentLoaded', () => {

  // ページ内すべての <button> 要素を取得
  document.querySelectorAll('button').forEach(btn => {

    // クリック直後にフォーカス枠を残さない
    btn.addEventListener('click', () => {

      // 80 ms 遅らせて blur() すると
      // 直前のクリック描画が終わった “次のフレーム” で
      // フォーカスが外れるため、UI がチラつかない
      setTimeout(() => btn.blur(), 80);
    });
  });

});

1.3. 主要命令まとめ

命令働き主な使い方
window.addEventListener('DOMContentLoaded', cb)HTML パース完了時に一度だけコールバック初期化コードの入口にする
document.querySelectorAll('button')DOM からすべての <button> を取得NodeList → forEach で反復
btn.addEventListener('click', cb)ボタンクリック時に処理を追加コントロール用の共通フック
setTimeout(cb, 80)CB を 80 ms 後に非同期実行レンダリング直後にフォーカス解除
btn.blur()要素のフォーカスを外すAndroid/iOS の連続タップ改善

1.4. 詳細解説 & ベストプラクティス

  • なぜ blur() が必要か
    物理キーボード環境ではフォーカス枠は便利ですが、スマホでは “残像” と感じやすく、次タップ時に誤作動を起こす場合があります。
  • setTimeout の 80 ms
    16 ms × 5 フレーム程度待てば十分に描画が済むので実測値でバッファを設けています。多すぎると UX が悪化、小さすぎると枠が残るため経験則で 80 ms 前後が妥当。
  • 今後の拡張例
    ローディングスピナーのグローバル制御や、共通トースト通知などもここに集約するとメンテナンスが楽になります。

2.dateFormat.js

2.1. 役割

  • 小さく・依存ゼロ の日時整形関数 dateFormat(fmt, date) を提供
  • 例:dateFormat('YYYY/MM/DD hh:mm', new Date()) → 2025/04/24 23:10

2.2. コメント付きソース

/* ---------------------------------------------------
   dateFormat.js
   - 軽量な日時フォーマッタ
   - 依存ライブラリ不要。Date オブジェクトをそのまま整形
--------------------------------------------------- */
function dateFormat(fmt, d = new Date()){

  // 1桁の数値をゼロ埋めするヘルパ
  const pad = (n) => String(n).padStart(2,'0');

  // フォーマット文字列を逐次置換
  return fmt
    .replace('YYYY', d.getFullYear())        // 年(4桁)
    .replace('MM'  , pad(d.getMonth()+1))    // 月(1 → 01)
    .replace('DD'  , pad(d.getDate()))       // 日
    .replace('hh'  , pad(d.getHours()))      // 時
    .replace('mm'  , pad(d.getMinutes()))    // 分
    .replace('ss'  , pad(d.getSeconds()));   // 秒
}

2.3. 主要命令まとめ

命令働き主な使い方
new Date()現在日時の取得省略引数で dateFormat() を即使用
String(n).padStart(2,'0')2桁ゼロ埋め01〜09 を保証
Date#getFullYear()4桁の年2025
Date#getMonth()0–11 の月+1 して 1–12 化
Date#getDate()日 (1–31)pad で 01–31
Date#getHours() / getMinutes() / getSeconds()時分秒24 h 表記を想定
String.replace(search, value)文字列置換6 回連続でフォーマット文字を実値へ

2.4. 使い方サンプル

// 例 1) 投稿日時表示
const createdAt = dateFormat('YYYY年MM月DD日 hh:mm', new Date());
// => "2025年04月24日 23:15"

// 例 2) ファイル名タイムスタンプ
const stamp = dateFormat('YYYYMMDD_hhmmss');
// => "20250424_231507"
カスタムトークン追加

replace() を追加するだけで簡単に拡張できます。

// 例 1) 投稿日時表示
const createdAt = dateFormat('YYYY年MM月DD日 hh:mm', new Date());
// => "2025年04月24日 23:15"

// 例 2) ファイル名タイムスタンプ
const stamp = dateFormat('YYYYMMDD_hhmmss');
// => "20250424_231507"

まとめ

  • common.jsUI 挙動の統一 に特化した“縁の下”ユーティリティ。
    ・ボタンフォーカス解除でスマホ UX 向上
  • dateFormat.jsたった 12 行 で強力な日時整形を実現。
    ・ライブラリ不要・依存ゼロで軽量

これら 2 ファイルだけでもコードの重複が大幅に減り、他モジュールの記述がシンプルになります。

次回は、 ローカルストレージを安全にラップする storage.js の設計と実装を解説します。