ul要素やol要素で作られたリストを、スマホではselect要素に切り替えたい場面があります。カテゴリ一覧やナビゲーションなど、PCではリストで並べたいけどSPではプルダウンにまとめたいケースです。
今回は、JavaScriptでリスト要素からselect要素を自動生成し、CSSのメディアクエリで表示を切り替える方法を紹介します。
CodePen ソースコードサンプル
完成イメージ
PCではul要素のリストがそのまま表示され、SPではselect要素のプルダウンに切り替わります:
<!-- PC:リスト表示 -->
<ul id="category-list" class="sp-select-target">
<li data-value="web">Web制作</li>
<li data-value="css">CSS</li>
<li data-value="js">JavaScript</li>
</ul>
<!-- SP:自動生成されるselect要素 -->
<select id="category-list-select" class="sp-select-generated">
<option value="web">Web制作</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
</select>
CSS:メディアクエリで表示切り替え
PCではselect要素を非表示、SPではリスト要素を非表示にします:
/* select要素はデフォルト非表示(PC) */
.sp-select-generated {
display: none;
}
/* SP:リストを非表示、selectを表示 */
@media (max-width: 768px) {
.sp-select-target {
display: none;
}
.sp-select-generated {
display: block;
}
}
JavaScript:リストからselectを自動生成
ページ読み込み時に、対象のリスト要素からselect要素を自動生成するコードです:
function generateSelectFromList(listElement) {
const listItems = listElement.querySelectorAll('li');
if (listItems.length === 0) return;
// select要素を生成
const select = document.createElement('select');
select.id = `${listElement.id}-select`;
select.className = 'sp-select-generated';
// リストアイテムからoptionを生成
listItems.forEach(item => {
const option = document.createElement('option');
option.value = item.dataset.value || item.textContent.trim();
option.textContent = item.textContent.trim();
select.appendChild(option);
});
// リスト要素の直後に挿入
listElement.parentNode.insertBefore(select, listElement.nextSibling);
return select;
}
// .sp-select-target を持つリストを一括変換
function initSpSelects() {
const lists = document.querySelectorAll('.sp-select-target');
lists.forEach(list => generateSelectFromList(list));
}
document.addEventListener('DOMContentLoaded', initSpSelects);
応用:リンク付きリストの変換
リスト内のa要素からhref属性を取得し、selectの変更時にページ遷移させるパターンです。カテゴリページへのナビゲーションなどで使えます:
<ul id="nav-list" class="sp-select-target">
<li><a href="/category/web/">Web制作</a></li>
<li><a href="/category/css/">CSS</a></li>
<li><a href="/category/js/">JavaScript</a></li>
</ul>
function generateSelectFromNavList(listElement) {
const listItems = listElement.querySelectorAll('li');
if (listItems.length === 0) return;
const select = document.createElement('select');
select.id = `${listElement.id}-select`;
select.className = 'sp-select-generated';
// デフォルトオプション
const defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = 'カテゴリを選択';
select.appendChild(defaultOption);
listItems.forEach(item => {
const link = item.querySelector('a');
const option = document.createElement('option');
option.value = link ? link.href : '';
option.textContent = item.textContent.trim();
select.appendChild(option);
});
// 選択時にページ遷移
select.addEventListener('change', function () {
if (this.value) {
window.location.href = this.value;
}
});
listElement.parentNode.insertBefore(select, listElement.nextSibling);
}
// リンク付きリストを変換
document.addEventListener('DOMContentLoaded', function () {
const navLists = document.querySelectorAll('.sp-select-target');
navLists.forEach(list => {
const hasLinks = list.querySelector('a');
if (hasLinks) {
generateSelectFromNavList(list);
} else {
generateSelectFromList(list);
}
});
});
コードの解説
ポイントは、JavaScriptでselect要素を生成し、CSSのメディアクエリで表示を制御する役割分担です。JSはあくまでDOMの生成だけを担当し、表示・非表示の切り替えはCSSに任せています。
.sp-select-targetクラスを付けたリスト要素が変換対象になります。data-value属性があればそれをoptionのvalueに、なければテキストの内容がそのままvalueになります。
応用例のリンク付きパターンでは、a要素のhref属性をoptionの値として取得し、changeイベントでwindow.location.hrefに代入することでページ遷移を実現しています。カテゴリページや固定ページへのナビゲーションをSPでプルダウン化したい場合に使えます。
まとめ
PCではリスト表示、SPではプルダウンに切り替えるレスポンシブパターンは静的サイトの制作でよく使います。CSSのメディアクエリとJavaScriptのDOM生成を組み合わせることで、HTMLの構造を変えずに対応できます。カテゴリ一覧やサイドバーのナビゲーションなど、SPで縦に場所を取りがちな要素に活用してください。
