vue拽横向滚动页面组件
拖拽bar横向滚动页面组件
拖拽横向滚动页面,效果图如下
<!--
* @description 滑块滚动条
!-->
<template>
<div ref="scrollBarBoxRef" class="scroll-bar-box">
<div class="line"></div>
<div v-if="isShowBar" ref="barRef" class="bar" @mousedown="startDrag" @mouseup="endDrag"></div>
</div>
</template>
<script>
export default {
name: 'ScrollBars',
props: {
// 需要滚动的容器
scrollClassName: {
type: String,
default: 'scroll-container-wp'
},
// 外层数据变化时,用来判断是否显示滚动bar
data: {
type: Array,
default: () => []
}
},
data() {
return {
dragging: false,
isShowBar: false,
scrollContainerEle: null
}
},
watch: {
data: {
handler() {
this.$nextTick(() => {
this.scrollContainerEle = document.querySelector(`.${this.scrollClassName}`)
const scrollContainerScrollWidth = this.scrollContainerEle.scrollWidth
const scrollContainerClientWidth = this.scrollContainerEle.clientWidth
this.isShowBar = scrollContainerScrollWidth > scrollContainerClientWidth
})
},
immediate: true,
deep: true
}
},
mounted() {
this.scrollContainerEle = document.querySelector(`.${this.scrollClassName}`)
this.scrollContainerEle.addEventListener('scroll', this.scrollContainerScroll)
window.addEventListener('resize', this.setBarFunc)
this.setIsShowBar()
const resizeObserver = new ResizeObserver(entries => {
this.setBarFunc()
})
resizeObserver.observe(this.scrollContainerEle)
},
beforeDestroy() {
this.scrollContainerEle.removeEventListener('scroll', this.scrollContainerScroll)
window.removeEventListener('resize', this.setBarFunc)
},
methods: {
setBarFunc() {
this.setIsShowBar()
this.setBarPosition()
},
setIsShowBar() {
const scrollContainerScrollWidth = this.scrollContainerEle.scrollWidth
const scrollContainerClientWidth = this.scrollContainerEle.clientWidth
this.isShowBar = scrollContainerScrollWidth > scrollContainerClientWidth
},
setBarPosition() {
if (!this.isShowBar) return
const scrollBarBoxRefWidth = this.$refs.scrollBarBoxRef.clientWidth
const scrollContainerScrollLeft = this.scrollContainerEle.scrollLeft
const scrollContainerScrollWidth = this.scrollContainerEle.scrollWidth
const scrollContainerClientWidth = this.scrollContainerEle.clientWidth
const maxScroll = scrollContainerScrollWidth - scrollContainerClientWidth
const scrollPercentage = scrollContainerScrollLeft / maxScroll
let left = scrollBarBoxRefWidth * scrollPercentage
// 左间距
if (left < 16) {
left = 16
}
// 减掉bar宽度
if (left > scrollBarBoxRefWidth - 52) {
left = scrollBarBoxRefWidth - 52
}
if (this.$refs.barRef && this.$refs.barRef.style) {
this.$refs.barRef.style.left = left + 'px'
}
},
startDrag() {
this.dragging = true
document.addEventListener('mousemove', this.doDrag)
document.addEventListener('mouseup', this.endDrag)
},
doDrag(event) {
if (this.dragging) {
const scrollBarBoxRefWidth = this.$refs.scrollBarBoxRef.clientWidth
const scrollBarBoxScreenLeft = this.$refs.scrollBarBoxRef.getBoundingClientRect().left
const barLeft = this.$refs.barRef.offsetLeft
const scrollContainerScrollWidth = this.scrollContainerEle.scrollWidth
const scrollContainerClientWidth = this.scrollContainerEle.clientWidth
let left = event.clientX - scrollBarBoxScreenLeft
if (left < 16) {
left = 16
}
if (left > scrollBarBoxRefWidth - 52) {
left = scrollBarBoxRefWidth - 52
}
if (this.$refs.barRef && this.$refs.barRef.style) {
this.$refs.barRef.style.left = left + 'px'
}
const maxScroll = scrollContainerScrollWidth - scrollContainerClientWidth
const scrollPercentage = barLeft / (scrollBarBoxRefWidth - 52)
this.scrollContainerEle.scrollTo({
left: left > 16 ? maxScroll * scrollPercentage : 0
})
}
},
endDrag() {
this.dragging = false
document.removeEventListener('mousemove', this.doDrag)
document.removeEventListener('mouseup', this.endDrag)
},
scrollContainerScroll() {
if (this.dragging) return
this.setBarPosition()
}
}
}
</script>
<style lang="scss" scoped>
.scroll-bar-box {
position: absolute;
height: 13px;
top: 0;
left: 0;
right: 0;
.line {
position: absolute;
top: 6px;
left: 0;
right: 0;
border-bottom: 1px solid #fce5c7;
}
.bar {
position: absolute;
width: 52px;
height: 13px;
top: 0;
left: 16px;
background: url('~@/assets/images/flow/ic_scroll_bar.png') no-repeat center center;
background-size: 100% 100%;
border-radius: 4px 0 0 4px;
cursor: pointer;
}
}
</style>
调用
本文来自博客园,作者:hong_li,转载请注明原文链接:https://www.cnblogs.com/hong1/p/18563316