【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で実装してみました。
コピペしてガンガン使ってください!
この記事に対するご意見・ご感想・ご質問等ありましたら、
ぜひ下記フォームにてお送りください。