セレクトボックス値変更時のページ遷移にURLオブジェクトを利用する

こんにちは、みやがわ です。

セレクトボックスの値変更と同時にページ遷移する挙動をMPAで実装する際に、
JavaScriptのURLオブジェクトを利用するのが便利だったのでご紹介します。

## やりたいこと
選択された値のvalueに対応するURLへの移動をJavaScriptで行っています。

[![Image from Gyazo](https://i.gyazo.com/f18cc557b38a2dc3a3f2caac9803534c.gif)](https://gyazo.com/f18cc557b38a2dc3a3f2caac9803534c)

<br>

## URLオブジェクトとは

文字通りURLをオブジェクトとして参照・変更するためのものです。

https://developer.mozilla.org/ja/docs/Web/API/URL

これを利用することで、URLを純粋な文字列操作よりも便利に扱うことができます。

参照の例

```jsx
const url = new URL('https://qiita.com/search?sort=&q=javascript#globalfooter');

url.href          // "https://qiita.com/search?sort=&q=javascript#globalfooter"
url.toString()    // "https://qiita.com/search?sort=&q=javascript#globalfooter"

url.origin        // "https://qiita.com"

url.protocol      // "https:"
url.host          // "qiita.com"
url.pathname      // "/search"
url.search        // "?sort=&q=javascript"
url.hash          // "#globalfooter"

url.searchParams  // URLSearchParams {size: 2}
Object.fromEntries(url.searchParams) // {sort: '', q: 'javascript'}
```

変更の例

```jsx
const url = new URL('https://qiita.com/search?sort=&q=javascript#globalfooter');

url.pathname = 'aaa';
url.hash = 'bbb';
url.searchParams.set('q', 'ccc')

url.href          // "https://qiita.com/aaa?sort=&q=ccc#bbb"
```

<br>

## セレクトボックスの値変更時にページ遷移する

これはURLの検索クエリの中のitemIdキーを変更して、ページ遷移する例です。

純粋な文字列操作と違い、URLの一部のみを簡単に参照や変更ができるので、複数の検索クエリのうち一部のみを変更したり、アンカーリンクを追加や変更する、などに活用できます。

挙動例

[![Image from Gyazo](https://i.gyazo.com/766bff3b39be56d5c838b09d230c822b.gif)](https://gyazo.com/766bff3b39be56d5c838b09d230c822b)


### サンプルコード

```html:html
<label for="items">Select items</label>

<select name="items" id="items" class="js_items">
    <option value="1">Apple</option>
    <option value="2">Banana</option>
    <option value="3">Lemon</option>
    <option value="4">Orange</option>
</select>
```

```jsx:js
const selectbox = document.querySelector('.js_items');
const url = new URL(window.location.href);
const searchKey = 'itemId';

document.addEventListener('DOMContentLoaded', (event) => {
  setInitialItem();
  selectbox.addEventListener('change', onChangeItemSelect);
});

/** セレクトボックス初期値を検索クエリに合わせてセット */
function setInitialItem() {
  selectbox.value = url.searchParams.get(searchKey) || 1;
}

/** セレクトボックス値変更時に検索クエリを変更してページ遷移 */
function onChangeItemSelect(event) {
  const selectbox = event.target;
  const itemId = event.target.value;

  url.searchParams.set(searchKey, itemId);

  window.location.href = url.toString();
}
```

<br>

## おわりに

よくあるUIで扱うデータは言語側が便利なオブジェクトを用意してくれていることがありますね。

存在自体を知らないと実装時に頭の中にすら上がってきませんので、
この記事で皆さんの実装の引き出しの1つになれば幸いです！

<br><br>

## 補足

URLのクエリパラメータ部が検索ボックスのフォーム要素と完全に一致する場合は、
上のように `window.location.href` で遷移させるのではなく、検索formを発火させる方法が良いと思います。

```html
<form action="" method="get">
    <select name="items" id="items" class="js_items">
        <option value="1">Apple</option>
        <option value="2">Banana</option>
        <option value="3">Lemon</option>
        <option value="4">Orange</option>
   </select>
</form>
```

```jsx
const searchForm = document.querySelector('.js_items');

document.addEventListener('DOMContentLoaded', (event) => {
  searchForm.addEventListener('change', (event) => {
    event.target.form.submit();
  });
});
```