JavaScript 逆引き集 | URLSearchParams(クエリ操作)

JavaScript JavaScript
スポンサーリンク

URLSearchParams の基本(クエリ操作) — const p = new URLSearchParams(location.search)

URL の「?以降」のクエリを簡単に読み書きできるのが URLSearchParamsget, set, append, delete, toString で直感的に扱えます。フォームの検索条件、ページの状態共有、フィルターの保持などに便利です。


まずは読み取りの基本

<script>
  // 例: https://example.com/?q=apple&page=2
  const p = new URLSearchParams(location.search);

  console.log(p.get("q"));    // "apple"
  console.log(p.get("page")); // "2"(文字列)
  console.log(p.has("sort")); // false(存在チェック)
</script>
HTML
  • 対象: location.search は現在ページのクエリ文字列。これを URLSearchParams に渡して操作します。
  • 戻り値の型: すべて文字列。数値にしたい場合は Number(...) で変換。

クエリの作成・編集(toString で反映)

// 新規に作って使う
const params = new URLSearchParams();
params.set("q", "apple");      // 置き換え(なければ追加)
params.set("page", "2");
params.append("tag", "red");   // 同キーを複数持たせたいとき(tag=red&tag=...)
params.append("tag", "fresh");

console.log(params.toString()); // "q=apple&page=2&tag=red&tag=fresh"
JavaScript
  • set と append の違い:
    • set: そのキーの値を「1つに」する(既存があれば置き換え)。
    • append: 値を「追加」する(同キー複数の列挙に向く)。

例題1: クエリで初期状態を決める(検索UI)

<input id="q" placeholder="検索語">
<select id="sort">
  <option value="new">新着</option>
  <option value="popular">人気</option>
</select>
<button id="apply">反映</button>

<script>
  // 1) 画面読み込み時にクエリから初期値を復元
  const p = new URLSearchParams(location.search);
  document.getElementById("q").value    = p.get("q")    || "";
  document.getElementById("sort").value = p.get("sort") || "new";

  // 2) 「反映」ボタンでクエリを書き換えてページ更新なしで履歴追加
  document.getElementById("apply").addEventListener("click", () => {
    const q = document.getElementById("q").value.trim();
    const sort = document.getElementById("sort").value;

    const next = new URLSearchParams(location.search);
    if (q) next.set("q", q); else next.delete("q");
    next.set("sort", sort);

    const url = `${location.pathname}?${next.toString()}${location.hash}`;
    history.pushState(null, "", url); // URLだけ更新(ページは再読み込みしない)

    // 必要ならここで検索処理を呼ぶ
    // performSearch({ q, sort });
  });
</script>
HTML
  • ポイント: history.pushState で「URLは更新、ページは保持」。戻る/進むで状態も追跡できます。

例題2: チェックボックス複数選択をクエリに保存

<label><input type="checkbox" name="tag" value="red">赤</label>
<label><input type="checkbox" name="tag" value="green">緑</label>
<label><input type="checkbox" name="tag" value="blue">青</label>
<button id="save">保存</button>

<script>
  // 初期復元(?tag=red&tag=blue のような複数値)
  const p = new URLSearchParams(location.search);
  const selected = p.getAll("tag"); // ["red","blue"]
  document.querySelectorAll('input[name="tag"]').forEach(ch => {
    ch.checked = selected.includes(ch.value);
  });

  // 保存(複数値は append で積む)
  document.getElementById("save").addEventListener("click", () => {
    const next = new URLSearchParams();
    document.querySelectorAll('input[name="tag"]:checked').forEach(ch => {
      next.append("tag", ch.value);
    });
    const url = `${location.pathname}?${next.toString()}`;
    history.replaceState(null, "", url); // 現在の履歴を書き換え
  });
</script>
HTML
  • ポイント: 複数値は getAllappendreplaceState は「履歴を積み増ししない更新」。

例題3: ベースURLからクエリを合成して遷移

function buildUrl(base, paramsObj) {
  const url = new URL(base, location.origin);
  const p = new URLSearchParams(paramsObj); // { q: "apple", page: 2 } など
  url.search = p.toString();
  return url.toString();
}

const link = buildUrl("/search", { q: "apple", page: 2, sort: "new" });
// "/search?q=apple&page=2&sort=new"
location.href = link; // 遷移
JavaScript
  • ポイント: new URL(base, origin) を使うと絶対/相対を意識せず安全に組み立てられます。

実務でのコツ

  • エンコードは任せてOK: URLSearchParams は自動で適切にエンコードします。生の文字列連結より安全。
  • 空文字/未設定の扱い: 空なら delete、値があるなら set のルールで一貫性を持つ。
  • 型の復元: 数値や真偽値は取得後に変換。
    • 例: const page = Number(p.get("page") || 1); const debug = p.get("debug") === "1";
  • 順序の安定: toString() の順序は追加した順が基本。テストで順序が必要なら、キー追加の順を固定する。
  • URLだけ更新したい: pushState/replaceState でページ遷移なしにURLを更新。イベントハンドラで状態を再反映する。

ありがちなハマりポイントと対策

  • 同キー複数を上書きしてしまう:
    • 対策: 複数値は append、読み取りは getAll
  • location.search を直接いじる:
    • 対策: 直接代入では遷移が発生しがち。合成して history.*State を使うと滑らか。
  • 未定義で Number(null)0 になる誤判定:
    • 対策: p.get(...) || default を挟んでから変換。
  • #hash との併用で消えてしまう:
    • 対策: 既存の location.hash を保持して URL を再構築。

練習問題(検索とソートのクエリを完全同期)

<input id="q" placeholder="検索語">
<select id="sort">
  <option value="new">新着</option>
  <option value="popular">人気</option>
</select>
<button id="apply">反映</button>

<script>
  function readParams() {
    const p = new URLSearchParams(location.search);
    return {
      q: p.get("q") || "",
      sort: p.get("sort") || "new",
    };
  }

  function writeParams({ q, sort }, push = true) {
    const p = new URLSearchParams();
    if (q) p.set("q", q);
    p.set("sort", sort);
    const url = `${location.pathname}?${p.toString()}${location.hash}`;
    (push ? history.pushState : history.replaceState).call(history, null, "", url);
  }

  // 初期反映
  const init = readParams();
  q.value = init.q; sort.value = init.sort;

  // 操作で反映
  document.getElementById("apply").addEventListener("click", () => {
    writeParams({ q: q.value.trim(), sort: sort.value }, true);
    // performSearch(...); // 実検索へ
  });

  // 戻る/進むでフォーム状態を更新
  window.addEventListener("popstate", () => {
    const cur = readParams();
    q.value = cur.q; sort.value = cur.sort;
    // performSearch(...); // 必要なら再実行
  });

  const q = document.getElementById("q");
  const sort = document.getElementById("sort");
</script>
HTML

直感的な指針

  • 読むときは new URLSearchParams(location.search)、書くときは set/append/delete → toString()
  • URLだけ更新したいなら history.pushState/replaceState を併用。
  • 複数値は getAll/append、型は取得後に変換して扱う。
タイトルとURLをコピーしました