0


uniapp 微信小程序和H5的弹窗滚动穿透解决

滚动穿透:

页面里的弹窗也是可以滚动的,然后页面本身内容多所以也是滚动的,就造成,在弹窗滚动的时候,页面内容也跟着滚动了。如图所示

ps: 电脑端分鼠标滚轮滚动和长按鼠标拖拽滚动,手机端只有触屏滑屏滚动,即像电脑端的长按鼠标拖拽滚动

我是在电脑上录屏的,所以两种情况的滚动穿透我都录上去

鼠标滚轮滚动的穿透

长按鼠标拖拽滚动的穿透

解决滚动穿透:

前提: 我用了UViewUi1.0版本的弹窗组件

Popup 弹出层 | uView - 多平台快速开发的UI框架 - uni-app UI框架

然后我的场景是内容局部滚动,UView提供的内容局部滚动方案如下:

所以结构是这样的

<u-popup mode="bottom" v-model="show">
    <view class="content">
        <scroll-view  scroll-y="true" style="height: 500rpx;">
            <view>
               局部内容局部内容
            </view>
        </scroll-view>
        <view class="confrim-btn">
            <u-button @click="show = false;">确定</u-button>
        </view>
    </view>
</u-popup>

1 解决电脑端长按鼠标拖拽滚动,即手机端的触屏滑屏滚动穿透问题(主要)

电脑端

重要代码:

@touchmove.stop.prevent="() => {}"

这句代码加在scroll-view上

手机端

重要代码(我找了好久才找到这个属性的):

overscroll-behavior-y: contain !important;

简单了解看这个:

https://www.jianshu.com/p/fb95e6552d13

完整学习看这个:

overscroll-behavior - CSS(层叠样式表) | MDN

这句代码是css的,因为用了UView的组件,所以这个要阻断滚轮链,就得要阻断真的滚动区域(最顶上的父级),直接加在我们的局部滚动scroll-view上是无效的,要加在最顶上的父级滚动区,这个需要你开调试者工具找,因为你可能用别的组件,多包了几层。

想改变深层元素的深层样式,代码如下

ps:

1、因为是改变了深层元素的样式,所以要手动刷新一下,不要热刷新,会没效果哈。

2、uniapp的插件引入,支持自己直接改源码的,所以,你可以直接去UView的弹窗文件里修改,就不用加 /deep/了。

2 解决电脑端的鼠标滚轮滚动穿透

其实是因为弹窗和弹窗的遮罩层(阴影层)没有阻止电脑端的鼠标滚轮滚动的操作,所以就导致了还存在鼠标滚轮滚动穿透。

这是是用了UView的组件的问题,所以直接去源码里改

重要代码

@mousewheel.prevent

遮罩层 u-mask:

弹窗 u-popup :

直接在这加,那弹窗的所有地方都不能鼠标滚动了,包括你自己的scrollview区域。

u-popup 的禁止滚轮滚动这个可以不弄,因为滚轮滚动挺方便的,想保留自己的scrollview区域的鼠标滚动,就要在非scrollview的地方加阻断滚轮事件的操作。而且只要加了下面的代码的,在你的局部滚动处(scrollview)滚轮滚动的穿透基本无了。

overscroll-behavior-y: contain !important;

我的完整效果代码(uview源码修改的就不贴了)

弹窗

<!-- @touchmove.stop.prevent 在u-popup已经设置了,所以触摸的滚动是阻断的,电脑鼠标滚轮滚动没阻断而已 -->
        <u-popup v-model="popupShow" mode="bottom" border-radius="24" @close="onPopupClose" duration="200">
            <view class="popup-view" v-if="popupShow">
                <block v-if="popuptype == 'pay'">
                    <view class="x space-between popup-view-title lightgrayborder">
                        <view class="main-title">
                            跟团购买
                        </view>
                        <u-icon name="close" color="#999999" size="28" @tap="onPopupClose"></u-icon>
                    </view>
                    <!-- @touchmove.stop.prevent="() => {}"  写在 scroll-view 里是为了兼容电脑端,阻断上下拖拽动作 ,手机端 使用 overscroll-behavior-y: contain !important;就足够阻断滚动穿透了,@mousewheel.prevent阻止电脑端滚轮滚动穿透-->
                    <scroll-view scroll-y="true" style="height: 500rpx;"
                        @touchmove.stop.prevent="() => {}">
                        <view class="x align-center popup-view-address">
                            <u-icon name="map" color="#FF384B" size="36"></u-icon>
                            <view class="y space-between mar-left">
                                <view class="x">
                                    <view class="boldfont">收货名字</view>
                                    <view class="mar-left">
                                        175891509xx
                                    </view>
                                </view>
                                <view class="spu-name" style="margin-top: 6rpx;">
                                    收货收货收货地址地址地址地址地址地址地址
                                </view>
                            </view>
                        </view>
                        <view class="x bgwhite lightgrayborder">
                            <u-image width="228rpx" height="228rpx"
                                src="https://img12.360buyimg.com/n1/jfs/t1/216488/12/17456/103503/6275c6ddE0b23753c/7387ff8f9b3e5ee3.jpg"
                                class="flex-shrink0" border-radius="10">
                            </u-image>
                            <view class="y space-between mar-left ">
                                <view class="spu-name boldfont">
                                    BEAUTY-FACTOR/美丽因子化妆刷套刷黑金8支套刷腮红刷眼影刷斜形眼线刷唇刷 黑金8支套刷
                                </view>
                                <view class="lightgrayfont">
                                    200ml
                                </view>
                                <view class="spu-price space-between">
                                    <view class="spu-price">
                                        <view class="price-etr">¥</view>398
                                    </view>
                                    <u-number-box v-model="buyCountNum" :min="numberBoxMin" :max="numberBoxMax"
                                        size="24" input-height="44"></u-number-box>
                                </view>
                            </view>
                        </view>
                        <view class="popup-view-actual-pay">
                            <view class="x space-between align-center">
                                <view class="">
                                    商品总价
                                </view>
                                <view class="boldfont">
                                    ¥398
                                </view>
                            </view>
                            <view class="x align-center flex-end " style="margin-top: 10rpx;">
                                <view class="mar-right">
                                    共1件
                                </view>
                                实际支付
                                <view class="spu-price" style="padding-bottom: 2rpx;">
                                    ¥398
                                </view>
                            </view>
                        </view>
                        <view class="bgwhite x align-center">
                            <view class="mar-right">
                                备注
                            </view>
                            <u-input style="flex:1;" type="text" placeholder="请输入您需要备注的内容" maxlength="150"
                                :trim="false" />
                        </view>
                    </scroll-view>
                    <view class="btn-topay">
                        立即支付 ¥398
                    </view>
                </block>
            </view>
        </u-popup>

弹窗内容样式

<style scoped lang="scss">
    page {
        background-color: #F5F3F7;
    }

    .groupbuy-detail {
        width: 100%;
        background-color: #F5F3F7;
    }

    .mar-left {
        margin-left: 22rpx;
    }

    .mar-right {
        margin-right: 22rpx;
    }

    .space-between {
        justify-content: space-between;
    }

    .flex-end {
        justify-content: flex-end;
    }

    .align-center {
        align-items: center;
    }

    .redfont {
        color: #F32E3C;
    }

    .lightgrayfont {
        color: #999999;
    }

    .boldfont {
        font-weight: bold;
    }

    .lightgrayborder {
        border-bottom: 1px solid rgba(153, 153, 153, 0.15);
    }

    .bgwhite {
        margin-top: 20rpx;
        margin-bottom: 20rpx;
        padding: 20rpx 24rpx;
        background: white;
    }

    .v-look-more {
        position: relative;
        top: -20rpx;
        padding: 20rpx;
        background: white;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .red-btn-r {
        color: #FFFFFF;
        background: #FF384B;
        border-radius: 10rpx;
    }

    .light-red-btn-r {
        opacity: 0.6;
    }

    .btn-follow {
        padding: 8rpx 30rpx;
        font-size: 26rpx;
    }

    .btn-buy {
        padding: 14rpx 26rpx;
        font-size: 26rpx;
    }

    .shop-infor {
        margin-top: 90rpx;
        background: #FFFFFF;
        border-radius: 24rpx 24rpx 0px 0px;
        position: relative;
    }

    .shop-logo {
        position: absolute;
        top: -38rpx;
        left: 44rpx;
    }

    .shop-btns {
        padding: 26rpx 46rpx;
        display: flex;
        justify-content: flex-end;
    }

    .shop-first-infor {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10rpx 43rpx;
    }

    .main-title {
        font-size: 32rpx;
        font-weight: bold;
        color: #333333;
        line-height: 38rpx;
    }

    .shop-second-infor {
        padding: 0rpx 43rpx;
        display: flex;

        .shop-second-infor-text {
            display: flex;
            align-items: center;
        }

        .shop-second-infor-text:nth-child(1)::after {
            content: '';
            width: 1px;
            height: 20rpx;
            background: #999999;
            margin-left: 20rpx;
            margin-right: 20rpx;
        }
    }

    .shop-intro {
        display: flex;
        align-items: baseline;
        margin-top: 30rpx;
        border-top: 1px solid rgba(153, 153, 153, 0.1);
        padding: 22rpx 44rpx 30rpx 44rpx;
        color: #666666;
    }

    .group-infor {
        margin-top: 20rpx;
        background: #FFFFFF;
        padding-bottom: 30rpx;
        width: 100%;
    }

    .group-title {
        font-size: 32rpx;
        font-weight: bold;
        color: #333333;
        padding: 42rpx 42rpx 24rpx 42rpx;
        // 识别换行符,手机端小程序不生效
        white-space: pre-line;
    }

    .group-intro {
        line-height: 38rpx;
        font-size: 28rpx;
        margin-bottom: 10rpx;
        white-space: pre-line;
    }

    .group-spu-1 {
        margin-left: 42rpx;
        margin-right: 42rpx;
        margin-bottom: 14rpx;
        border-radius: 10rpx;
        background: #F8F8F8;
        display: flex;
        align-items: center;
        padding: 20rpx 22rpx;
    }

    .group-spu-1-title {
        display: flex;
        align-items: center;
        width: 78rpx;
        word-wrap: break-word;
        // 不允许收缩
        flex-shrink: 0;
        position: relative;

        &::after {
            position: absolute;
            right: 0rpx;
            bottom: -4rpx;
            content: '';
            width: 1px;
            height: 84rpx;
            background: rgba(153, 153, 153, 0.3);
        }
    }

    .flex-shrink0 {
        flex-shrink: 0;
    }

    .spu-name {
        text-align: left;
        word-break: break-all; // 英文换行
    }

    .omit {
        display: -webkit-box;
        -webkit-text-overflow: ellipsis;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    .spu-price {
        margin-top: 4rpx;
        display: flex;
        align-items: flex-end;
        font-size: 34rpx;
        font-weight: bolder;
        color: #F32E3C;

        .price-etr {
            padding-bottom: 4rpx;
            font-size: 24rpx;
            font-weight: normal;
        }
    }

    .group-second-infor {
        font-size: 22rpx;
        padding: 6rpx 42rpx 0rpx 42rpx;
        display: flex;
        color: #999999;

        .group-second-infor-text {
            display: flex;
            align-items: center;
        }

        .group-second-infor-text:nth-child(1)::after {
            content: '';
            width: 1px;
            height: 20rpx;
            background: #999999;
            margin-left: 20rpx;
            margin-right: 20rpx;
        }
    }

    .v-category-title {
        line-height: 45rpx;
        display: flex;
        align-items: center;
        font-size: 32rpx;
        font-weight: bolder;
        color: #333333;
        margin-bottom: 6rpx;
        box-sizing: border-box;
    }

    .v-category-title::before {
        content: '';
        width: 6rpx;
        height: 26rpx;
        border-radius: 6rpx;
        background: #FF384B;
        // margin-left: 28rpx;
        margin-right: 10rpx;
    }

    .v-btns {
        border-bottom: 2rpx solid #F5F3F7;
        position: fixed;
        bottom: 0;
        width: 100%;
        padding: 22rpx;
        background-color: #FFFFFF;
        display: flex;
        justify-content: space-between;

        .btn {
            flex: 1;
            font-size: 32rpx;
            padding: 20rpx;
            margin: 0rpx auto;
            border-radius: 12rpx;
            view-align: center;
            text-align: center;
            border: 1px solid #FF384B;
        }

        .btn-fill {
            color: #fff;
            background: #FF384B;
        }

        .btn-empty {
            color: #FF384B;
            background: #FFFFFF;
            margin-right: 22rpx;
        }

    }

    .popup-view {
        width: 100%;
        display: flex;
        flex-direction: column;
        background-color: #F5F3F7;
        border-radius: 30rpx 30rpx 0px 0px;

        .popup-view-title {
            background: #FFFFFF;
            padding: 28rpx 33rpx;
        }

        .popup-view-address {
            background: #FFFFFF;
            padding: 24rpx 33rpx;
        }

        .popup-view-actual-pay {
            background: #FFFFFF;
            padding: 26rpx 26rpx 22rpx 26rpx;
            // display: flex;
            justify-content: flex-end;
        }

        .btn-topay {
            height: 100rpx;
            background: #FF384B;
            color: #FFFFFF;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 34rpx;
        }
    }

    /deep/ .uni-scroll-view {
        // 在真正的滚动区域设置 阻断滚动穿透
        overscroll-behavior-y: contain !important;
    }
</style>

script

popupShow: false,
popuptype: 'pay',
// 步进器
buyCountNum: 1,
// 剩余数量
restNum: 0,
numberBoxMin: 0,
numberBoxMax: 0,

因为从自己代码里扣出来的,所以可能漏东西,但是问题不大,漏啥你们再自己补补就好了。

ps:

最后发现,在手机端我一个手指长按屏幕的在弹窗滑倒底部的时候,手指不松开,马上把另一个手的手指按住屏幕不松开的滑上滑下,发现还是存在滚动穿透了,只有这样操作的情况下才存在,所以我的解决方法没有很完美,如果你有其他的好法子请告诉我,谢谢。

搜了一下,一只手指按住屏幕另一只手指划得动屏幕叫做多点触控。


本文转载自: https://blog.csdn.net/weixin_43991241/article/details/127083673
版权归原作者 坐等夕阳落time 所有, 如有侵权,请联系我们删除。

“uniapp 微信小程序和H5的弹窗滚动穿透解决”的评论:

还没有评论