在vue中封装一个betterscroll组件,并解决ios、Android在微信页面上下拉出现滑动的问题
最近在开发微信公众号网页的时候,发现使用原生滚动的时候,ios在微信网页下,上拉,下拉都会出现一大片的空白,看起来极其的别扭,为了解决这一问题,找了许多参考资料,如下是解决方法。1.首先在你需要禁止滑动的页面中添加如下代码mounted(){document.body.addEventListener('touchmove',function (e)...
最近在开发微信公众号网页的时候,发现使用原生滚动的时候,ios在微信网页下,上拉,下拉都会出现一大片的空白,看起来极其的别扭,为了解决这一问题,找了许多参考资料,如下是解决方法。
1.首先在app.vue的mounted中添加如下代码
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="scrollContainer" class="scroll-container">
<slot />
</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
},
/** 是否开启纵向滚动 */
scrollY: {
type: Boolean,
default: true
},
/** 是否派发滚动事件 */
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
}
},
data() {
return {
scroll: null
}
},
watch: {
/* 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常 */
data() {
setTimeout(() => {
this.refresh()
}, this.refreshDelay)
}
},
mounted() {
/* 保证在DOM渲染完毕后初始化better-scroll */
this.$nextTick(() => {
this._initScroll()
})
},
methods: {
/**
* @description: better-scroll的初始化
*/
_initScroll() {
if (!this.$refs.scrollContainer) {
return
}
this.scroll = new BScroll(this.$refs.scrollContainer, {
probeType: this.probeType,
click: this.click, // 是否派发click事件
useTransition: false, // 防止iphone微信滑动卡顿
scrollX: this.scrollX, // 横向可滑动,默认为false
scrollY: this.scrollY, // 纵向可滑动,默认为true
preventDefault: true, // 是否阻止默认事件
momentum: true, // 当快速滑动时是否开启滑动惯性
bounce: false, // 是否启用回弹动画效果
mouseWheel: true // pc端手机滚动
})
/* 是否派发滚动事件 */
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')
})
}
},
/**
* @description: 禁用 better-scroll
*/
disable() {
this.scroll && this.scroll.disable()
},
/**
* @description: 启用 better-scroll,默认开启
*/
enable() {
this.scroll && this.scroll.enable()
},
/**
* @description: 强制 scroll 重新计算,当 better-scroll 中的元素发生变化的时候调用此方法。
*/
refresh() {
this.scroll && this.scroll.refresh()
},
/**
* @description:滚动到某个位置
* @param {Number} x x轴的坐标
* @param {Number} y y轴的坐标
* @param {Number} time 动画时间
*/
scrollTo(x, y, time) {
this.scroll && this.scroll.scrollTo(x, y = 0, time)
},
/**
* @description:滚动到某个元素
* @param {Object} el dom 元素(必填)
* @param {Number} time 动画时间
* @param {Number} offsetX x轴偏移量,设置为true时,到达目标元素中心位置
* @param {Number} offsetY y轴偏移量,设置为true时,到达目标元素中心位置
*/
scrollToElement(el, time, offsetX, offsetY) {
this.scroll && this.scroll.scrollToElement(el, time, offsetX, offsetY)
}
}
}
</script>
<style lang="scss" scoped>
.scroll-container {
overflow: hidden;
}
</style>
举个使用例子:
<better-scroll
ref="scrollPane"
:data="routes"
:scroll-x="true"
:scroll-y="false"
class="el-menu-wrapper"
>
<el-menu
ref="elMenu"
class="el-menu-content"
>
<el-menu-item>.....<el-menu-item/>
</el-menu>
</better-scroll>
........
// .el-menu的宽度必须大于.el-menu-wrapper的宽度,才会产生滚动效果
.el-menu-wrapper {
width: 100%;
}
.el-menu {
display: inline-block;
white-space: nowrap;
}
}
使用的例子都在上面的代码里面了,如果你有很多地方需要使用到这个组件,你可以在main.js里面全局使用这个组件
import scroll from 'components/Scroll.vue'
Vue.component('scroll', scroll)
最后按照代码的方法使用这个组件,就能够很完美的解决页面上拉下拉出现滑动的问题。
这里还有第二种处理方式,有时候滚动条不能滚动有可能是由于ios页面底部出现导航造成的,可参考这篇文章解决vue单页面在iOS微信浏览器中弹出底部栏导致的样式问题
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)