问题
在上一篇文章初级无限滚动我们介绍了无限滚动的思路
和方法
,但是有个明显的问题,当我快速上滑的时候是没有实现惯性的
效果。
![](https://img.haomeiwen.com/i17768770/099f22828d70191b.gif)
方案
所以针对改问题我们可以自己写一个js来控制它的滚动,但是没有这个必要,因为有现成的库已经帮我们做了这件事情了,他就是alloytouch.js
alloytouch npm官网地址
ps:因为某家node - v 是v8.11.2 而它最低版本支持是 v10.13.0 ,所以我只能被迫下载使用了
前提概要
1.既然要做无限滚动,所以背景图片的大小应该是已知的,所以本demo就设置成已知 1762px
以下是源码
<template>
<div class="intermediate-view">
<div class="lvl-bg"></div>
<div class="content" :class="isLayoutH && 'layout-h'" id="content" ref="content"
:style="isLayoutH && { width: pageW + 'px' }" >
<div v-for="(page, pIdx) in pages" :key="pIdx" :style="{ top: page.y + 'px'}"
:class="['group', 'L', { 'snd-page': page.isLast }]" ></div>
</div>
</div>
</template>
<script>
import Touch from "../../../utils/touch.js";
export default {
data() {
return {
pageW: 0,
screenH: 0,
isLayoutH: false,
bgImgsH: 1762,
pages: [
{
y: 0,
},
{
y: 0,
},
],
scrollPosition: { x: 0, y: 0 },
bgH: null,
stepTapLock: false,
};
},
mounted() {
let _sw = window.innerWidth;
let _sh = window.innerHeight;
if (_sw > _sh) {
_sw = Math.ceil(_sh * 0.9);
this.isLayoutH = true;
}
this.pageW = _sw;
this.screenH = _sh;
this.bgImgsH = this.getRatioVal(this.bgImgsH);
this.bgH = this.bgImgsH;
this.pages[1].y = -1 * this.bgH;
document.body.addEventListener("touchmove", this.touchmoveEvt, {
passive: false,
});
this.initAlloytouch();
},
methods: {
getRatioVal(val) {
// 保留一位小数点
const ratio = this.pageW / 750;
return Math.ceil(val * 10 * ratio) / 10;
},
touchmoveEvt(evt) {
evt.preventDefault();
},
initAlloytouch() {
let pageMin = this.getRatioVal(-100000);
let pageMax = this.getRatioVal(100000);
this.scrollTouch = new Touch({
touch: "#content",
target: this.scrollPosition,
property: "y",
factor: 1,
moveFactor: 1,
preventDefault: false,
bindSelf: false,
max: pageMax,
min: pageMin,
change: () => {
this.updatePageRender();
},
touchMove: () => {
this.stepTapLock = true;
},
touchEnd: () => {
this.stepTapLock = false;
},
});
},
updatePageRender() {
this.updatePagePositon();
},
updatePagePositon() {
let p = this.scrollPosition.y;
let h = this.bgH;
let offset = p % h;
let v = Math.floor(Math.abs(p) / h) % 2;
this.pages.forEach((item, i) => {
let m = 1;
if (p < 0) {
m = -1;
}
item.y = offset + (i + v - 1) * h * (-2 * v + 1) * m;
});
if (this.pages[0].y < this.pages[1].y) {
this.pages[0].isLast = true;
this.pages[1].isLast = false;
} else if (this.pages[1].y < this.pages[0].y) {
this.pages[0].isLast = false;
this.pages[1].isLast = true;
}
},
},
};
</script>
<style lang="scss" scoped>
.intermediate-view {
width: 100%;
height: 100%;
position: relative;
background-color: #1990fe;
overflow: hidden;
.lvl-bg {
position: absolute;
width: 100%;
height: 100%;
background-size: 100%;
filter: blur(20px);
background-image: url("../../../assets/step-bg2.png");
}
.content {
width: 100%;
height: 100%;
position: relative;
margin: 0 auto;
&.layout-h {
box-shadow: 2px -2px 4px 0px rgba(51, 51, 51, 0.2);
}
}
.group {
position: absolute;
left: 0;
width: 100%;
background-size: 100%;
&.L {
height: 1762px;
background-image: url("../../../assets/step-bg2.png");
}
&.snd-page {
// 解决page间不吻合的问题(缝隙)
transform: translateY(3px);
}
}
}
</style>
效果如下
![](https://img.haomeiwen.com/i17768770/6f106061a94a3fff.gif)
![](https://img.haomeiwen.com/i17768770/35dacea1d1a6ce9d.gif)
附录:
如果这篇不清楚的话可以看看上一期内容:
vue 初级无限滚动
alloytouch.js 在 码云 vue-question 项目中
另外附录两个 alloytouch源码解析地址 :
网友评论