JSFiddle - React, Tailwind, and code Playground
by essoduke chang
HTML
<div class="nav-container">
<div class="slider"></div>
<ul>
<li class="item"><div>Item A</div></li>
<li class="item active"><div>Item B</div></li>
<li class="item"><div>Item C</div></li>
<li class="item"><div>Item D</div></li>
</ul>
</div>
CSS
.nav-container {
position: relative;
display: inline-block;
}
ul {
list-style: none;
position: relative;
display: inline-flex;
background: transparent;
padding: 0;
border-radius: 4px;
}
ul li {
display: inline-block;
padding: 0px 16px;
cursor: pointer;
position: relative;
z-index: 1;
}
ul li.item.active {
color: white;
}
.slider {
position: absolute;
background-color: #080;
height: calc(100% - 18px);
top: 10px;
transition: transform 0.3s ease;
border-radius: 4px;
z-index: 0;
}
JavaScript
const items = document.querySelectorAll('.item');
const slider = document.querySelector('.slider');
const ul = document.querySelector('ul');
const container = document.querySelector('.nav-container');
// 滑動開始的回調函式
function onSlideStart() {
console.log('滑動開始');
// 在這裡添加滑動開始時要執行的程式碼
}
// 滑動結束的回調函式
function onSlideEnd() {
console.log('滑動結束');
// 在這裡添加滑動結束時要執行的程式碼
}
// 監聽滑動事件
slider.addEventListener('transitionstart', onSlideStart);
slider.addEventListener('transitionend', onSlideEnd);
// 初始化滑塊位置
function updateSliderPosition() {
const activeItem = document.querySelector('.item.active');
if (activeItem) {
const itemWidth = activeItem.offsetWidth;
const itemLeft = activeItem.offsetLeft;
slider.style.width = `${itemWidth}px`;
slider.style.transform = `translateX(${itemLeft}px)`;
}
}
// 初始設置
updateSliderPosition();
items.forEach(el => {
el.addEventListener('click', (e) => {
items.forEach(i => i.classList.remove('active'));
const self = e.currentTarget;
self.classList.add('active');
updateSliderPosition();
console.log(self.textContent);
})
});