最近在开发微信公众号网页的时候,发现使用原生滚动的时候,ios在微信网页下,上拉,下拉都会出现一大片的空白,看起来极其的别扭,为了解决这一问题,找了许多参考资料,如下是解决方法。
1.首先在你需要禁止滑动的页面中添加如下代码
mounted(){
document.body.addEventListener(
'touchmove',
function (e) {
e.preventDefault()
},
{ passive: false }
)
}
当你设置完后会发现,ios\Android下页面确实不能上拉下拉了,但是页面也不能滑动了,大部分博客告诉完你这个方法之后都不会告诉你接下来的解决办法,实属坑人啊,以下是我的解决方法。因为上面那个代码会把所有原生的滚动都禁止掉,所以这里我建议用betterscroll代替原生的滚动。
2.安装betterscroll代替原生的scroll,这样页面就可以滑动了
npm install better-scroll
然后我把betterscroll组件封装了一下
<!--
参数解释在props中
使用说明:
<scroll
class="wrapper"
:data="data"
>
<div class="content">
</div>
</scroll>
要想betterScroll产生滚动效果,你需要设置'.wrapper'的高度,content的内容高度必须要高于warpper的高度才会显示出滚动条
如果content里面内容的高度是不固定的,那么需要给scroll传值data
-->
<template>
<div ref="wrapper" class="scroll">
<div class="scroll-wrap">
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
props: {
/* 传1 滚动的时候会派发scroll事件,会截流。
传2 滚动的时候实时派发scroll事件,不会截流。
传3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件 */
probeType: {
type: Number,
default: 1
},
// 点击列表是否派发click事件
click: {
type: Boolean,
default: true
},
// 是否开启横向滚动
scrollX: {
type: Boolean,
default: false
},
// 是否派发滚动事件
listenScroll: {
type: Boolean,
default: false
},
// 列表的数据,用于数据改变导致视图更改后重新初始化滚动
data: {
type: Array,
default: null
},
/** * 是否派发滚动到底部的事件,用于上拉加载 */
pullup: {
type: Boolean,
default: false
},
/** * 是否派发顶部下拉的事件,用于下拉刷新 */
pulldown: {
type: Boolean,
default: false
},
/** * 是否派发列表滚动开始的事件 */
beforeScroll: {
type: Boolean,
default: false
},
/** * 当数据更新后,刷新scroll的延时。 */
refreshDelay: {
type: Number,
default: 20
}
},
watch: {
// 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常
data () {
setTimeout(() => {
this.refresh()
}, this.refreshDelay)
}
},
mounted () {
// 保证在DOM渲染完毕后初始化better-scroll
setTimeout(() => {
this._initScroll()
}, 20)
},
methods: {
_initScroll () {
if (!this.$refs.wrapper) {
return
}
// better-scroll的初始化
this.scroll = new BScroll(this.$refs.wrapper, {
probeType: this.probeType,
click: this.click,
useTransition: false, // 防止iphone微信滑动卡顿
scrollX: this.scrollX,
preventDefault: true,
momentum: true,
bounce: false // 阻止scroll的弹性动画
})
// 是否派发滚动事件
if (this.listenScroll) {
const me = this
this.scroll.on('scroll', pos => {
me.$emit('scroll', pos)
})
}
// 是否派发滚动到底部事件,用于上拉加载
if (this.pullup) {
this.scroll.on('scrollEnd', () => {
// 滚动到底部
if (this.scroll.y <= this.scroll.maxScrollY + 50) {
this.$emit('scrollToEnd')
}
})
}
// 是否派发顶部下拉事件,用于下拉刷新
if (this.pulldown) {
this.scroll.on('touchend', pos => {
// 下拉动作
if (pos.y > 50) {
this.$emit('pulldown')
}
})
}
// 是否派发列表滚动开始的事件
if (this.beforeScroll) {
this.scroll.on('beforeScrollStart', () => {
this.$emit('beforeScroll')
})
}
},
disable () {
// 代理better-scroll的disable方法
this.scroll && this.scroll.disable()
},
enable () {
// 代理better-scroll的enable方法
this.scroll && this.scroll.enable()
},
refresh () {
// 代理better-scroll的refresh方法
this.scroll && this.scroll.refresh()
},
scrollTo () {
// 代理better-scroll的scrollTo方法
this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
},
scrollToElement () {
// 代理better-scroll的scrollToElement方法
this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
}
}
}
</script>
<style lang="less" scoped>
.scroll {
overflow: hidden;
}
</style>
使用的例子都在上面的代码里面了,如果你有很多地方需要使用到这个组件,你可以在main.js里面全局使用这个组件
import scroll from 'components/Scroll.vue'
Vue.component('scroll', scroll)
最后按照代码的方法使用这个组件,就能够很完美的解决页面上拉下拉出现滑动的问题。