vue 横向滚动组件
最近遇到这么一个需求,就是内容一行显示,滚轮滚动的时候,进行横向滚动。
本来想尝试下css能不能做到,最后发现,即便改变了流的布局,并不能改变滚动条的方向,最后还是只能用js做了。
滚动兼容性
滚轮只存在pc的时候,所以触摸事件是不考虑的,触摸的话可以直接用better-scroll插件。
滚动事件需要兼容火狐和谷歌:
- 火狐滚动事件:DOMMouseScroll
- 谷歌滚动事件:mousewheel
其中DOMMouseScroll的event对象,他有一个detail字段,向下滚动是3,往上滚动是-3
mousewheel的event对象是deltaY,往下滚动是125,往上是-125,具体数值记不清了,反正是这样。
兼容的情况就是这样了,字段不同。
组件代码
创建一个CrosswiseScroll.vue
组件
代码如下:
<template>
<div
class="crosswise-scroll"
@DOMMouseScroll.prevent="mouseTranslate"
@mousewheel.prevent="mouseTranslate"
>
<div
class="crosswise-content"
ref="crosswiseContent"
:style="'transform: translateX(' + translateX + 'px);'"
>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
translateX: 0, //滚动的距离
maxTranslateX: 0, //最大滚动距离
};
},
methods: {
// 鼠标滚轮滑动事件
mouseTranslate(event) {
if (!this.maxTranslateX) this.countMaxTranslateX();
const delta = event.deltaY || event.detail;
let x = this.translateX;
if (delta > 0) {
x =
Math.abs(x - 100) >= this.maxTranslateX
? -this.maxTranslateX
: x - 100;
} else {
x = x + 100 >= 0 ? 0 : x + 100;
}
this.translateX = x;
},
//计算最大滚动距离
countMaxTranslateX() {
if (!this.crosswiseContent) {
this.crosswiseContent = this.$refs.crosswiseContent;
}
this.maxTranslateX =
this.crosswiseContent.scrollWidth - this.crosswiseContent.offsetWidth;
if (Math.abs(this.translateX) >= this.maxTranslateX) {
this.translateX = -this.maxTranslateX;
}
},
},
created() {
//计算最大滚动距离
// this.$nextTick(() => {
// this.countMaxTranslateX();
// });
},
mounted() {
window.addEventListener("resize", this.countMaxTranslateX, false);
},
beforeDestroy() {
window.removeEventListener("resize", this.countMaxTranslateX, false);
},
};
</script>
<style lang="scss" scoped>
.crosswise-scroll {
overflow-x: hidden;
.crosswise-content {
transition: transform 0.1s;
}
}
</style>
使用
<template>
<crosswise-scroll>
...需要横向滚动显示的内容
</crosswise-scroll>
</template>
<script>
import CrosswiseScroll from "CrosswiseScroll";
export default {
components: {
CrosswiseScroll,
}
}
</script>
注意:
- 横向滚动的内容自身不能
overflow: hidden
简单点来理解就是,横向滚动的内容就是内容的实际宽度,他可以超出容器宽度,因为我们横向滚动就是为了应对这种情况的。
评论(0)