uni-app scroll-view 循环加载组件 组件中包含多个view 和 uni-popup 此时弹框只能在scroll-view可视范围内显示

uni-app scroll-view 循环加载组件 组件中包含多个view 和 uni-popup 此时弹框只能在scroll-view可视范围内显示

开发环境 版本号 项目创建方式
Windows win11专业版 24H2 HBuilderX

产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:win11专业版 24H2

HBuilderX类型:正式

HBuilderX版本号:4.75

手机系统:iOS

手机系统版本号:iOS 18

手机厂商:苹果

手机机型:11

页面类型:vue

vue版本:vue3

打包方式:云端

示例代码:

<template>
  <view>
    <view class="zh-wrapper">
      <scroll-view scroll-y style="width: 250rpx;height: 100%;touch-action:none;">
      </scroll-view>
      <scroll-view scroll-y style="flex: 1;height: 100%;overflow: hidden;background-color: #ffffff;">
        <view v-for="(item,index) in list">
          <comter></comter>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script>
import comter from './comter.vue'
export default {
  data() {
    return {
      list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }
  },
  components: {
    comter
  }
}
</script>

<template>
  <view>
    <view @click="$refs.explainPopup.open()"> 11111111</view>
    <view @click="$refs.explainPopup.open()"> 11111111</view>
    <view @click="$refs.explainPopup.open()"> 11111111</view>
    <view @click="$refs.explainPopup.open()"> 11111111</view>
    <view @click="$refs.explainPopup.open()"> 11111111</view>
    <uni-popup ref="explainPopup" type="center">
      <view class="anstistop">
        <image class="antistop_title_image" src="/static/app/model/top_banner.png"></image>
        <view class="antistop_title_div">
          <text class="antistop_title">
            提示
          </text>
        </view>
        <view class="antistop_center">
          <text class="antistop_center_text">
            {{12121212121212121}}
          </text>
        </view>
        <view class="p-btn" @click="close">  
          <text class="new_antistop_bottom">我知道了</text>  
        </view>  
      </view>  
    </uni-popup>
  </view>
</template>

<style>
.anstistop {
  width: 286px;
  padding-bottom: 1px;
  background-color: white;
  border-radius: 8px;
}

/* 其他样式省略 */
</style>

操作步骤:

  • 点击view后弹框

预期结果:

  • 正常全屏弹框

实际结果:

  • 仅在scroll-view可视范围内显示

bug描述:

scroll-view 循环加载组件 组件中包含多个view 和 uni-popup 此时弹框有问题,当组件内只有一个view和uni-popup时弹框正常,仅iOS环境,Android、鸿蒙、H5正常


更多关于uni-app scroll-view 循环加载组件 组件中包含多个view 和 uni-popup 此时弹框只能在scroll-view可视范围内显示的实战教程也可以访问 https://www.itying.com/category-93-b0.html

9 回复

可以把uni-popup放到父级页面中 comter组件内点击后触发自定义事件 父级页面监听并打开uni-popup组件 这样就不会被包裹在scroll-view中了

更多关于uni-app scroll-view 循环加载组件 组件中包含多个view 和 uni-popup 此时弹框只能在scroll-view可视范围内显示的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是目前最好的解决办法

这个问题的确奇怪,相同的产物在 ios 上表现不一致,目前看到 ios 中 overflow-y 的表现比较特殊,你给你的 right scroll-view 添加一个 right-view 的 class name   .right-view > .uni-scroll-view > .uni-scroll-view {
    /* #ifdef APP-PLUS /
    overflow-x: auto!important;
    overflow-y: hidden!important
    /
 #endif */
  }

这样是可以弹出了,但是无法滚动了

回复 亿企查: 目前看是 overflow-x 在 app web 组件上表现有差异,相同的代码在安卓上正常,在 ios 上渲染异常,应该是兼容性问题。这个建议通过抽离组件做事件通信的方案来操作。如果有进一步的发现,可以继续评论跟进。

放在root-portal 组件里面就没问题了

这种方式仅在小程序有用,我们现在是在iOS APP环境

目前最佳方案是把uni-popup移出来,不放在scroll-view里面,后续看情况吧,safari 有兼容性问题

这是一个常见的 iOS 滚动容器内弹窗显示限制问题。由于 iOS 的渲染机制,scroll-view 内的 uni-popup 弹窗会被限制在父级滚动容器的可视区域内。

解决方案:

  1. 将 uni-popup 移到 scroll-view 外部 将弹窗组件提升到页面最外层,避免被 scroll-view 的滚动区域限制:
<template>
  <view>
    <view class="zh-wrapper">
      <scroll-view scroll-y style="width: 250rpx;height: 100%;">
      </scroll-view>
      <scroll-view scroll-y style="flex: 1;height: 100%;background-color: #ffffff;">
        <view v-for="(item,index) in list" :key="index">
          <comter :item="item" @show-popup="showPopup"></comter>
        </view>
      </scroll-view>
    </view>
    
    <!-- 弹窗移到最外层 -->
    <uni-popup ref="explainPopup" type="center">
      <view class="anstistop">
        <image class="antistop_title_image" src="/static/app/model/top_banner.png"></image>
        <view class="antistop_title_div">
          <text class="antistop_title">提示</text>
        </view>
        <view class="antistop_center">
          <text class="antistop_center_text">{{popupContent}}</text>
        </view>
        <view class="p-btn" @click="close">  
          <text class="new_antistop_bottom">我知道了</text>  
        </view>  
      </view>  
    </uni-popup>
  </view>
</template>

<script>
export default {
  data() {
    return {
      list: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      popupContent: ''
    }
  },
  methods: {
    showPopup(content) {
      this.popupContent = content
      this.$refs.explainPopup.open()
    },
    close() {
      this.$refs.explainPopup.close()
    }
  }
}
</script>
  1. 在 comter 组件中通过事件触发 修改 comter 组件,通过事件传递弹窗显示:
<!-- comter.vue -->
<template>
  <view>
    <view @click="$emit('show-popup', '12121212121212121')">11111111</view>
    <!-- 其他 view 元素 -->
  </view>
</template>
回到顶部