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

news2025/2/23 23:58:19

滚动穿透:

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

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:

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405891.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频实时行为检测——基于yolov5+deepsort+slowfast算法

文章目录前言一、核心功能设计二、核心实现步骤1.yolov5实现目标检测2.deepsort实现目标跟踪3.slowfast动作识别三、核心代码解析1.参数2.主函数3.将结果保存成视频总结前言 前段时间打算做一个目标行为检测的项目&#xff0c;翻阅了大量资料&#xff0c;也借鉴了不少项目&…

【Java】运算符

我不去想是否能够成功 既然选择了远方 便只顾风雨兼程 —— 汪国真 目录 1. 认识运算符 1.1 认识运算符 1.2 运算符的分类 2. 算术运算符 2.1 四则运算符 2.2 复合赋值运算符 2.3 自增 / 自减 运算符 3.关系运算符 4.逻辑运算符 4.1 逻辑与 && 4.2 逻…

什么是异步

文章目录 前言一、异步是什么&#xff1f;二、举个例子来理解异步 1.异步最典型的例子就是“回调函数”总结前言 在vue的过程中&#xff0c;我们一定会遇到诸如&#xff1a; function&#xff08;参数&#xff09;.then(res>{}) 形式的代码。到底怎么编译执行的呢 &#xf…

【Jetpack】ViewModel 架构组件 ( 视图 View 和 数据模型 Model | ViewModel 作用 | ViewModel 生命周期 | 代码示例 | 使用注意事项 )

文章目录一、Activity 遇到的问题二、视图 View 和 数据模型 Model三、ViewModel 架构组件作用四、ViewModel 代码示例1、ViewModel 视图模型2、Activity 组件3、UI 布局文件4、运行效果五、ViewModel 生命周期六、ViewModel 使用注意事项一、Activity 遇到的问题 Activity 遇到…

宝塔部署nodejs项目

前言 部署操作很简单&#xff0c;网上也有很多教程&#xff0c;不过我还是踩坑了&#xff0c;这里记录一下&#xff0c;给其他人也避避坑吧。 步骤 首先你已经有了服务器&#xff0c;并且打开了宝塔面板&#xff0c;其次准备好你的nodejs项目。 在宝塔安装pm2管理器&#xf…

Nginx 调整文件上传大小限制

使用3A服务器做了网页&#xff0c;感觉挺不错的&#xff0c;使用LNMP环境 用Nginx部署了前端&#xff0c;发现上传附件大一点就会报错&#xff0c;查看配置文件&#xff0c;发现spring的附件配置已经配置了。那么就看下Nginx的body设置。nginx文件上传默认是1MB。 在 server 模…

VUE3TS: Vue3+TS的项目搭建

简介 通过 Vue-cli4 创建的 Vue3TS 的项目&#xff0c;并进行一些基础使用的举例。 此例是以 VSCode编辑器 进行的编码。 一、项目搭建 1. 进入命令提示符窗口 在要搭建项目的文件夹中&#xff0c;点击路径&#xff0c;输入CMD并按回车 2. 查看node版本、Vue-cli版本 2…

Android 架构之长连接技术

上文中我们提到了HttpDNS&#xff0c;虽然它比系统DNS更优&#xff0c;但终归还是要做DNS操作。而长连接都是IP直接连接&#xff0c;因此没有DNS相关的开销和耗时。 3. 如果有大量网络请求&#xff0c;可以明显减少网络延时&#xff0c;节省带宽 对于大型App而言&#xff0c;…

npm——安装、卸载与更新

npm 官方文档&#xff1a;https://docs.npmjs.com/ 什么是npm npm&#xff08;“Node 包管理器”&#xff09;是 JavaScript 运行时 Node.js 的默认程序包管理器。 它也被称为“Ninja Pumpkin Mutants”&#xff0c;“Nonprofit Pizza Makers”&#xff0c;以及许多其他随机…

Vue通知提醒框(Notification)

项目相关依赖版本信息 可自定义设置以下属性&#xff1a; 自动关闭的延时时长&#xff08;duration&#xff09;&#xff0c;单位ms&#xff0c;默认4500ms消息从顶部弹出时&#xff0c;距离顶部的位置&#xff08;top&#xff09;&#xff0c;单位像素px&#xff0c;默认24p…

WebSocket开发(心跳监测)功能

前言 在之前的文章中完成了客服对话的Demo功能&#xff0c;但是现在的连接是无限制的长时间连接没有做心跳、失活、超时断连等功能&#xff0c;心跳的实现方法有很多种&#xff0c;并且WebSocket就提供了ping/pong类型的消息。 心跳的触发方式也分两种&#xff1a; 客户端触…

微信小程序实现图片上传

前言 手机上传图片的功能大家一定都用过吧&#xff0c;今天教你用微信小程序实现这个小功能。 实现效果如下&#xff1a; 实现思路&#xff1a; 首先我们需要定义一个存放图片的数组&#xff0c;通过方法拿取图片的详细信息&#xff0c;然后调用微信小程序的 wx.uploadFile 方…

element ui datepicker时间控件实现范围选择周,季,年。

因项目要求&#xff0c;需日&#xff0c;周&#xff0c;月&#xff0c;季&#xff0c;年五种日期范围选择器&#xff0c;故参考文章&#xff08;在末尾&#xff09;后分享 一.效果图 二、版本及下载 1.实现需要修改源码&#xff0c;目前修改的版本为2.15.3&#xff0c;所以想要…

Vue3路由配置createRouter、createWebHistory、useRouter,useRoute

目录 手动配置Vue-router环境&#xff1a; 组件内部跳转路由、传参useRouter,useRoute Vue3和Vue2基本差不多&#xff0c;只不过需要将createRouter、createWebHistory从vue-router中引入&#xff0c;再进行使用。 手动配置Vue-router环境&#xff1a; 1、下载包&#xff1a…

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘result‘)

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading result) 如题所示问题&#xff0c;耽误三天寻找bug&#xff0c;终于在我睡意朦胧之际发现了一道光&#xff0c;发现 await 出现的三个点&#xff1a; 于是打开 findAllCategory()这个函数 对应…

电商后台管理系统简介

项目介绍 黑马后台管理系统是一个电商后台管理系统的前端项目&#xff0c;基于VueElement实现。 主要包括商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等功能 开发技术 此项目开发我用到的技术有&#xff1a;vue2node.…

Vant 2 - 移动端 Vue 组件库 _ 问题记录

目录 Popup 弹出层 DatetimePicker 时间选择 Field 输入框 Picker 选择器 List 列表 Tab 标签页 发布初衷 &#xff1a; 记录在移动端项目中使用 Vant 2 组件库时遇到的各种问题 &#xff0c; 方便以后再次遇到类似问题 &#xff0c; 能够快时查阅解决 &#xff0c; …

Vue3+TypeScript+Vite如何使用require动态引入类似于图片等静态资源

问题&#xff1a;Vue3TypeScriptVite的项目中如何使用require动态引入类似于图片等静态资源&#xff01; 描述&#xff1a;今天在开发项目时&#xff08;项目框架为Vue3TypeScriptVite&#xff09;需要 动态引入静态资源&#xff0c;也就是img标签的src属性值为动态获取&#…

Lodash 使用及常用方法

简介 Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。 官网 Lodash 简介 | Lodash 中文文档…

TypeScript详解十六:类型声明(declare)

目录前言一、类型声明的作用&#xff1f;1.1 declare 关键字1.2 示例二、常见的几种类型声明2.1 普通类型声明2.2 外部枚举2.3 命名空间三、类型声明文件3.1 模拟类型声明文件&#xff0c;以 jquery 为例3.2 使用手动实现的jquery.d.ts声明文件3.3 第三方声明文件&#xff08;以…