タブ切り替えを実装する

jsでコンテンツのタブ切り替えを実装するコード。

  • コンテンツ切り替えのタブメニューは上下で連動する
  • 下側のタブメニューをクリックしたら、スムーススクロールでコンテンツ上部まで移動する

HTML

<div class="tab_menu">
<ul>
<li class="active">tabA</li>
<li>tabB</li>
<li>tabC</li>
</ul>
</div>
<div class="contents_area" id="contents_area">
<div class="conte active">
<p>tabAのコンテンツ</p>
</div>
<div class="conte">
<p>tabBのコンテンツ</p>
</div>
<div class="conte">
<p>tabCのコンテンツ</p>
</div>
</div>
<div class="tab_menu">
<ul>
<li class="active" data-url="contents_area">tabA</li>
<li data-url="contents_area">tabB</li>
<li data-url="contents_area">tabC</li>
</ul>
</div>

JavaScript

const contents_area = document.getElementById('contents_area');
const tab_menu = document.querySelectorAll('.tab_menu');
const tabItems = document.querySelectorAll('.tab_menu li');
const conte = Object.values(document.querySelectorAll('.conte'));
function partition(array, n) {
return array.length ? [array.splice(0, n)].concat(partition(array, n)) : [];
}
const tab_list = partition(Object.values(tabItems), tabItems.length / 2);
tab_menu.forEach(function(elm, i) {
function tabChange(e) {
const index = tab_list[i].indexOf(e.target);
for (const elm of tabItems) {
elm.classList.remove('active')
}
for (const elm of conte) {
elm.classList.remove('active')
}
for (const elm of tab_list) {
elm[index].classList.add('active')
}
conte[index].classList.add('active')
//ページ内アンカーアンカー
if (e.target.hasAttribute('data-url')) {
window.scrollTo({
top: contents_area.offsetTop,
behavior: 'smooth'
});
};
}
elm.addEventListener('click', tabChange);
})

activeを外すfor...ofはもうちょっと違う書き方がある気がする。

jQuery

ついでにjQueryでのコード。

$(function() {
const tab_li = $('.tab_menu li');
$(tab_li).click(function() {
const index = $(this).parent().children('li').index(this);
const current_conte = $('.conte');
$('.tab_menu').each(function() {
$('li', this).removeClass('active').eq(index).addClass('active');
});
$(current_conte).eq(index).addClass('active').siblings('div, section').removeClass('active');
});
//ページ内アンカーアンカー
$('.tab_menu:last-of-type li').click(function() {
const speed = 400;
const href= `#${$(this).attr('data-url')}`;
const target = $(href == "#" || href == "" ? 'html' : href);
const position = target.offset().top;
$('html, body').stop().animate({scrollTop:position}, speed, 'swing');
return false;
});
});