上毛印刷株式会社

【JavaScript】PCではリスト、スマホではセレクトにタグ切り替え

【JavaScript】PCではリスト、スマホではセレクトにタグ切り替え

2024年12月06日
WEBサイト制作
  • #HTML
  • #css
  • #JavaScript
  • #tips

こんにちは!
上毛印刷WEB制作担当のソーヤです。

今回は、少し特殊なtipsを紹介します!

以前、とあるディレクターが「お知らせ一覧を作りたいんだけど、サイドバーの表示は、PCはリスト表示で、スマホはセレクト表示にして」と指示をだしました。
私は、「タグが変わるのか・・・じゃあサイドバーをPC・スマホで2パターン作って出し分けるか」と考えていたところ、そのディレクターが「2パターン出し分けはやめて!運用ミスに繋がるから!」と言いました。

正直なところ、内心「いや、このサイト、CMSいれるんだから、無理やりPC・スマホ同一タグにする必要ないでしょ」と思いましたが、頑張って実装しました!

実装例


スマホでみるか、ブラウザ幅を狭めてリロードしてください。
セレクト表示に切り替わっていると思います!

HTML例

<div class="news-menu">
  <div class="news-select-wrap">
    <select id="group_menu01" class="news-select">
      <option class="news-option select-text-change1" selected="">カテゴリ選択</option>
      <option class="news-option" value="/news/">ALL</option>
      <option class="news-option" value="/group/">グループ</option>
      <option class="news-option" value="/corp/">コーポレーション</option>
      <option class="news-option" value="/facility/">ファシリティー</option>
    </select>
  </div>
  <div class="news-select-wrap">
    <select id="group_menu02" class="news-select">
      <option class="news-option select-text-change2" selected="">年代選択</option>
      <option value="/2021/" class="news-option"> 2021 年</option>
      <option value="/2020/" class="news-option"> 2020 年</option>
      <option value="/2019/" class="news-option"> 2019 年</option>
      <option value="/2018/" class="news-option"> 2018 年</option>
      <option value="/2017/" class="news-option"> 2017 年</option>
      <option value="/2016/" class="news-option"> 2016 年</option>
      <option value="/2015/" class="news-option"> 2015 年</option>
      <option value="/2014/" class="news-option"> 2014 年</option>
      <option value="/2013/" class="news-option"> 2013 年</option>
      <option value="/2012/" class="news-option"> 2012 年</option>
      <option value="/2011/" class="news-option"> 2011 年</option>
      <option value="/2010/" class="news-option"> 2010 年</option>
    </select>
  </div>
</div>

CSS例

.news-menu{
  width: 60%;
  margin: auto;
}
.news-select{
  list-style: none;
}
.news-option{
  padding: 10px;
  background-color: #eee;
  border-bottom: 1px solid #aaa;
}
@media screen and (max-width: 768px) {
  .news-menu{
    width: 100%;
  }
  .news-select-wrap{
    margin: auto;
    width: 300px;
  }
  .news-select{
    width: 100%;
  }
}

JavaScript例

document.addEventListener('DOMContentLoaded', function () {
  function getVal() {
    var newsOptions = document.querySelectorAll('.news-option');
    newsOptions.forEach(function (option) {
      option.addEventListener('click', function () {
        var url = this.getAttribute('value');
        if (url) {
          window.location.href = url;
        }
      });
    });
  }
  function getVal2() {
    var selects = document.querySelectorAll('select');
    selects.forEach(function (select) {
      select.addEventListener('change', function () {
        var url2 = this.value;
        if (url2) {
          window.location.href = url2;
        }
      });
    });
  }
  function changeTag() {
    if (window.matchMedia('(max-width: 768px)').matches) {
      document.querySelectorAll('.news-select').forEach(function (selectElement) {
        var tagClass = selectElement.getAttribute('class') || '';
        var tagId = selectElement.getAttribute('id') || '';
        var selectHTML = selectElement.innerHTML;
        var newSelect = document.createElement('select');
        if (tagClass) newSelect.setAttribute('class', tagClass);
        if (tagId) newSelect.setAttribute('id', tagId);
        newSelect.innerHTML = selectHTML;
        selectElement.replaceWith(newSelect);
      });
      document.querySelectorAll('.news-option').forEach(function (optionElement) {
        var tagClass = optionElement.getAttribute('class') || '';
        var tagValue = optionElement.getAttribute('value') || '';
        var optionHTML = optionElement.innerHTML;
        var newOption = document.createElement('option');
        if (tagClass) newOption.setAttribute('class', tagClass);
        if (tagValue) newOption.setAttribute('value', tagValue);
        newOption.innerHTML = optionHTML;
        optionElement.replaceWith(newOption);
      });
      var textChange1 = document.querySelector('.select-text-change1');
      var textChange2 = document.querySelector('.select-text-change2');
      if (textChange1) textChange1.textContent = 'カテゴリ選択';
      if (textChange2) textChange2.textContent = '年代選択';
      getVal2();
    } else {
      document.querySelectorAll('select').forEach(function (selectElement) {
        var tagClass = selectElement.getAttribute('class') || '';
        var tagId = selectElement.getAttribute('id') || '';
        var selectHTML = selectElement.innerHTML;
        var newUl = document.createElement('ul');
        if (tagClass) newUl.setAttribute('class', tagClass);
        if (tagId) newUl.setAttribute('id', tagId);
        newUl.innerHTML = selectHTML;
        selectElement.replaceWith(newUl);
      });
      document.querySelectorAll('option').forEach(function (optionElement) {
        var tagClass = optionElement.getAttribute('class') || '';
        var tagValue = optionElement.getAttribute('value') || '';
        var optionHTML = optionElement.innerHTML;
        var newLi = document.createElement('li');
        if (tagClass) newLi.setAttribute('class', tagClass);
        if (tagValue) newLi.setAttribute('value', tagValue);
        newLi.innerHTML = optionHTML;
        optionElement.replaceWith(newLi);
      });
      var textChange1 = document.querySelector('.select-text-change1');
      var textChange2 = document.querySelector('.select-text-change2');
      if (textChange1) textChange1.textContent = 'カテゴリ選択';
      if (textChange2) textChange2.textContent = '年代選択';
      getVal();
    }
  }
  getVal();
  getVal2();
  changeTag();
  window.addEventListener('resize', changeTag);
});

まとめ

今回もjQueryではなく、Vanilla.jsで実装してみました。

コピペしてガンガン使ってください!

WEB制作担当ソーヤ

ソーヤ

上毛印刷WEB制作担当
前職は東証プライム企業の本社WEB受託チームにてフロントエンドエンジニアを3年経験。


この記事に対するご意見・ご感想・ご質問等ありましたら、
ぜひ下記フォームにてお送りください。

    お名前必須
    メールアドレス必須
    お問い合わせ内容必須
    PAGE TOP