效果:
<div class="categoryList-category">
<div class="scrollbar-width0 unmover" id="scrollbarCategory">
<div class="categoryList-category-left">
<div
class="category-item"
:class="'category-item' + index"
:id="'categoryItem' + index"
v-for="(item, index) in categoryList"
:key="item.item_clsno"
@click="tabchenage(item, index)"
>
<div
class="category-item-div"
:class="current == index ? ['activeItem'] : ''"
>
{{ item.item_clsname }}
</div>
</div>
</div>
</div>
<div class="categoryList-category-search" @click="toShowSearchInput()">
<em class="iconfont icon-31sousuo"></em>
</div>
</div>
样式
.categoryList-category {
display: flex;
align-items: center;
// background-color: var(--bg-primary);
border-radius: 4px;
height: @saleScrollbarHeight;
padding-left: 10px;
background-color: var(--bg-icon);
.scrollbar,
.scrollbar-width0 {
overflow-x: auto;
flex: 1;
width: 610px;
margin-right: 10px;
}
&-left {
display: flex;
align-items: center;
.category-item {
/*width: 82px;*/
flex-shrink: 0;
cursor: pointer;
height: @saleScrollbarHeight;
display: flex;
justify-content: center;
align-items: center;
&-div {
min-width: 82px;
height: 40px;
border-radius: 4px;
padding: 0 8px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: var(--sales-category-color);
}
}
.activeItem {
background-color: var(--sales-categoryact-bg);
color: var(--sales-categoryact-color);
font-size: 18px;
font-weight: bold;
position: relative;
&:before {
content: '';
display: block;
width: 4px;
height: 24px;
background: var(--sales-categoryact-selected-bg);
border-radius: 0px 2px 2px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
}
}
&-search {
width: 56px;
flex-shrink: 0;
border-left: 1px solid var(--sales-categorysel-color);
display: flex;
justify-content: center;
cursor: pointer;
em {
font-size: 26px;
}
}
}
js
const current = ref<number>(0)
const tabchenage = (item: ClsList, index: number, type?: string) => {
if (current.value == index) return
current.value = index
handleScroll(index)
}
const handleScroll = (index: number) => {
let scrollToLeft: boolean = false // 是否向左滑动
if (index > currentIndex) {
// 左滑
scrollToLeft = true
} else {
scrollToLeft = false
}
currentIndex = index
// 当前元素
let currEle: any = document.querySelector('.category-item' + index)
let currEleWidthStr = ''
if (currEle) {
currEleWidthStr = window.getComputedStyle(currEle)?.width // 当前元素的宽度
}
let currEleWidth: number = 0
if (currEleWidthStr) {
currEleWidth = Number(Number(currEleWidthStr.split('p')[0]).toFixed(2))
}
let currEleLeft = currEle?.offsetLeft || 0 // 当前元素距离左边的位置
// 下一个元素
let nextEle: any = document.querySelector('.category-item' + (index + 1))
let nextEleWidthStr: string = ''
let nextEleWidth: number = 0
let nextEleLeft: number = 0
if (nextEle) {
nextEleWidthStr = window.getComputedStyle(nextEle).width
nextEleWidth = Number(Number(nextEleWidthStr.split('p')[0]).toFixed(2))
nextEleLeft = nextEle.offsetLeft
} else {
// 最后一个元素,下一个宽度等于当前元素宽度
nextEleWidth = currEleWidth
nextEleLeft = currEleLeft
}
// 上一个元素
let previousEle: any = document.querySelector('.category-item' + (index - 1))
let previousEleWidthStr: string = ''
let previousEleWidth: number = 0
let previousEleLeft: number = 0
if (previousEle) {
previousEleWidthStr = window.getComputedStyle(previousEle).width
previousEleWidth = Number(
Number(previousEleWidthStr.split('p')[0]).toFixed(2)
)
previousEleLeft = previousEle.offsetLeft
} else {
// 最后一个元素,上一个宽度等于当前元素宽度
previousEleWidth = currEleWidth
previousEleLeft = currEleLeft
}
const scrollBox: any = document.querySelector('#scrollbarCategory') // 滚动盒子
const scrollbarWidth: number = scrollBox!.clientWidth // 滚动盒子的宽度
const scrollL = scrollBox.scrollLeft // 滚动条滚动的距离
if (scrollToLeft) {
// 下一个元素的到左边的距离加上自身的宽度如果大于了滚动盒子的宽度,说明被遮挡了,需要滚动
let nextEleLeftWidth = nextEleLeft + nextEleWidth
// 左滑
if (nextEleLeftWidth > scrollbarWidth) {
scrollBox.scrollTo({
left: scrollL + nextEleWidth,
behavior: 'smooth'
})
}
} else {
let previousEleScrollLWidth = scrollL + previousEleWidth
if (previousEleScrollLWidth > previousEleLeft)
// 右滑
scrollBox.scrollTo({
left: scrollL - previousEleWidth,
behavior: 'smooth'
})
}
}