vue 之 左右滑动,底下滚动条跟随
效果图
分析与实现
- 手指拖着往左走,那么下面的小红条就应该往右走!
- 上面手指拖着往左走的距离 / 下面小红条向走走的距离 = 上面总 / 下面总
<!-- -->
<template>
<div class="hot_nav">
<div class="hot_nav_con">
<div class="hot_nav_inner">
<div class="hot_item" v-for="(item,index) in 16" :key="item">我是item {{index }}</div>
</div>
<div class="hot_nav_bottom">
<div class="hot_nav_bottom_inner" :style="innerBarStyle"></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "HotNav",
components: {},
data() {
return {
// 1:屏幕的宽度
screenW:
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth,
// 2:滚动内容的宽度
scrollContentW: 750,
// 3:滚动条的背景长度
bgBarW: 100,
// 4:滚动条的长度
barXWidth: 0,
// 5:开始的位置
startX: 0,
// 6:结束的位置
endFlag: 0,
// 7:移动的位置
barMoveWidth: 0
};
},
mounted() {
this.getBottomBarWidth();
this.bindEvent();
},
computed: {
innerBarStyle() {
return {
width: `${this.barXWidth}px`,
left: `${this.barMoveWidth}px`
};
}
},
methods: {
// 获取滚动条的长度
getBottomBarWidth() {
this.barXWidth = this.bgBarW * (this.screenW / this.scrollContentW);
},
// 移动端事件监听
bindEvent() {
// $el 当前组件
this.$el.addEventListener("touchstart", this.handleTouchStart, false);
this.$el.addEventListener("touchmove", this.handleTouchMove, false);
this.$el.addEventListener("touchend", this.handleTouchEnd, false);
},
// 开始触摸
handleTouchStart(e) {
// 1:获取第一个触点
// console.log("e", e.touches[0]);
let touch = e.touches[0];
//2:求出起始点
this.startX = Number(touch.pageX);
},
// 开始移动
handleTouchMove(e) {
// 1:获取第一个触点
let touch = e.touches[0];
// 2:求 上面移动的距离
let moveWidth = Number(touch.pageX) - this.startX;
// 3-1:根据上面移动的距离 判断是左滑 还是右滑
// 3:求出 下面滚动条的距离 = -(滚动条的背景长度 / 内容的滚动长度) * 上面移动的距离
if (moveWidth < 0) {
// 右滑
this.barMoveWidth =
-(this.bgBarW / this.scrollContentW) * moveWidth - this.endFlag;
if (this.barMoveWidth >= this.bgBarW - this.barXWidth) {
//右边
this.barMoveWidth = this.bgBarW - this.barXWidth;
}
} else {
// 左滑
this.barMoveWidth =
this.endFlag - (this.bgBarW / this.scrollContentW) * moveWidth;
if (this.barMoveWidth <= 0) {
this.barMoveWidth = 0;
}
console.log("左滑", this.barMoveWidth);
}
},
// 结束触摸
handleTouchEnd() {
this.endFlag = this.barMoveWidth;
}
}
};
</script>
<style lang="scss" scoped>
.hot_nav {
position: relative;
width: 100%;
height: 180px;
background: #fff;
.hot_nav_con {
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
&::-webkit-scrollbar {
display: none;
}
.hot_nav_inner {
display: flex;
flex-wrap: wrap;
width: 720px;
height: 100%;
.hot_item {
width: 90px;
height: 90px;
background: pink;
}
}
.hot_nav_bottom {
width: 100px;
height: 2px;
background: #ccc;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 8px;
.hot_nav_bottom_inner {
position: absolute;
left: 0;
height: 100%;
background: orange;
width: 0;
}
}
}
}
</style>