返回

弹出框滚屏问题破解:uni-popup与scroll-view完美兼容

前端

避免uni-popup组件和scroll-view滚动组件之间滚动冲突

在使用uni-popup组件和scroll-view滚动组件时,可能会遇到一个令人头疼的问题:在uni-popup组件内滚动时,也导致页面上的scroll-view滚动。这无疑是一种烦人的体验,如何解决呢?

解决方案

这里有两个行之有效的解决方案:

  1. 在uni-popup上添加滚动禁止事件和样式
<uni-popup @touchmove.stop.prevent style="height: 100vh;">

@touchmove.stop.prevent禁止滚动事件,而height: 100vh;将uni-popup组件的高度设置为100%视口高度。

  1. 弹出popup后禁止页面的touchmove事件
handlePopupOpen() {
  // 当弹出框打开时,禁止页面的touchmove事件
  document.body.style.touchmove = 'none';
},
handlePopupClose() {
  // 当弹出框关闭时,解除页面的touchmove事件禁止
  document.body.style.touchmove = '';
},

这两种方法都能有效解决滚动冲突问题。

示例代码

为了更直观地理解,这里提供一个完整的示例代码:

<template>
  <view class="container">
    <scroll-view scroll-y style="height: 100vh;">
      <!-- 页面内容 -->
    </scroll-view>
    <uni-popup
      v-model="showPopup"
      @open="handlePopupOpen"
      @close="handlePopupClose"
      @touchmove.stop.prevent
      style="height: 100vh;"
    >
      <!-- 弹出框内容 -->
      <scroll-view scroll-y style="height: 100vh;">
        <!-- 弹出框滚动内容 -->
      </scroll-view>
    </uni-popup>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showPopup: false,
    };
  },
  methods: {
    handlePopupOpen() {
      // 当弹出框打开时,禁止页面的touchmove事件
      document.body.style.touchmove = 'none';
    },
    handlePopupClose() {
      // 当弹出框关闭时,解除页面的touchmove事件禁止
      document.body.style.touchmove = '';
    },
  },
};
</script>

<style>
.container {
  height: 100vh;
}
</style>

常见问题解答

  1. 为什么会出现滚动冲突?

这是因为uni-popup组件和scroll-view组件都使用了overflow: auto;样式,当在uni-popup组件内滚动时,scroll-view组件的滚动条也会被触发,从而导致页面上的scroll-view也滚动。

  1. 为什么两种解决方案都可以解决问题?

第一种解决方案通过阻止uni-popup组件内的滚动事件,而第二种解决方案通过禁止页面上的touchmove事件,从而间接禁止了scroll-view组件的滚动。

  1. 哪个解决方案更好?

第一种解决方案更简洁,但如果需要在popup中实现其他滚动行为,可能会带来不便。第二种解决方案更灵活,但需要在弹出和关闭popup时处理touchmove事件的禁止和解除。

  1. 除了代码解决方案,还有什么其他办法可以解决?

可以尝试使用touch-action: none;样式或css-overflow-scrolling: touch;属性来禁止滚动,但效果可能因浏览器和设备而异。

  1. 如何避免未来出现此类问题?

在使用uni-popup组件和scroll-view组件时,建议尽量避免在两者内部都使用滚动,以减少冲突的可能性。