• 小程序齐层看板 scrollview 解决抖动


            

        这个图分解成4块 上左:楼层    上右:基础数据  下左:固定文字  下右:楼栋

        楼层可上下滑动

        楼栋可左右滑动

             基础信息可上下左右滑动

             楼层scroll-view 与基础信息scroll-view 上下滑动关联

          楼栋scroll-view 与基础信息scroll-view 左右滑动关联

       当同时滑动  楼层与基础信息 并且滑动方向相反就会导致scroll事件的监听进入死循环导致页面抖动

      为了解决这个问题就设想同时只能滑动一个scroll-view

           就写了三个遮罩层在三个scroll-view上

           当 一个scroll-view 触发了 touchstart 事件其他两个scroll-view 上面的遮罩层显示

        当 scroll-view 触发了 touchend 事件三个scroll-view 上面的遮罩层隐藏

           这样就解决了同时触发两个@scroll事件进入死循环

    <template>
    	<view :style="'height:' + scrollViewHeight + ';'" id="scroll-v3" class="projectProgress">
    		<view v-if="isFloorMask" class="floor-mask"></view>
    		<view v-if="isTableMask" :style="'height:' + tableHeight + ';'" class="table-mask"></view>
    		<view v-if="isBuildingMask" class="building-mask"></view>
    		<!-- 楼层和项目构件进度汇总 -->
    		<view class="floorsTable">
    			<scroll-view @touchend="hideMask" @touchstart="floorTouchstart" @scroll="floorScrollHandler" scroll-y="true"
    				:scroll-top="floorScrollTop" :scroll-anchoring="true" style="height: 100%;  174rpx">
    				<view class="floors">
    					<view class="floorItem" v-for="floor in floorsList" :key="floor">{{ floor }}层</view>
    				</view>
    			</scroll-view>
    			<scroll-view @touchend="hideMask" @touchstart="tableTouchstart" @scroll="tableScrollHandler" scroll-x="true" scroll-y="true"
    				:scroll-top="tableScrollTop" :scroll-left="tableScrollLeft" :scroll-anchoring="true"
    				style="height: 100%;  calc(100vw - 174rpx)">
    				<view class="allComponents">
    					<view class="componentTable">
    						<componentTable v-for="(buildingItem, index) in boardsInfo" :key="index"
    							:boardsInfo="buildingItem" :floorsList="floorsList">
    						</componentTable>
    					</view>
    				</view>
    			</scroll-view>
    		</view>
    		<!-- 楼栋和构件类型 -->
    		<view class="projectInfo">
    			<view class="title"> 项目详情 </view>
    			<scroll-view @touchend="hideMask" @touchstart="buildTouchstart" @scroll="buildingScrollHandler" scroll-x="true"
    				:scroll-left="buildingScrollLeft" :scroll-anchoring="true"
    				style=" calc(100vw - 170rpx); height: 196rpx">
    				<view class="buildingAndType">
    					<BuildingAndType v-for="(buildingItem, index) in boardsInfo" :key="index"
    						:building="buildingItem.buildingName" :typeList="buildingItem.typeList">
    					</BuildingAndType>
    				</view>
    			</scroll-view>
    		</view>
    	</view>
    </template>
    
    <script>
    	import debounce from "@/utils/deBounce.js";
    	import BuildingAndType from "./BuildingAndType.vue";
    	import componentTable from "./componentTable.vue";
    	import {
    		getBillBoardsList
    	} from "@/api/project.js";
    	export default {
    		name: "ProjectProgress",
    		components: {
    			BuildingAndType,
    			componentTable,
    		},
    		props: {
    			projectId: {
    				type: Number,
    			},
    		},
    		created() {
    			this.getBillBoardsList();
    		},
    		data() {
    			return {
    				tableHeight:'calc(100vh -20px - 44px - 44px - 196rpx)',
    				isFloorMask: false,
    				isBuildingMask: false,
    				isTableMask: false,
    				scrollViewHeight: "80vh",
    				floorScrollTop: 0,
    				tableScrollTop: 0,
    				tableScrollLeft: 0,
    				buildingScrollLeft: 0,
    
    				floorScrollFunc: false,
    				tableScrollFunc: false,
    				buildingScrollFunc: false,
    
    				floorTimer: null,
    				tableTimer: null,
    				buildingTimer: null,
    
    				boardsInfo: [],
    				floorsList: [],
    			};
    		},
    		mounted() {
    			uni.getSystemInfo({
    				success: (resu) => {
    					this.tableHeight = `calc(100vh - ${resu.statusBarHeight}px - 44px - 44px - 196rpx)`
    					const query = uni.createSelectorQuery();
    					query.select("#scroll-v3").boundingClientRect();
    					query.exec((res) => {
    						this.scrollViewHeight =
    							`calc(${resu.windowHeight}px - ${resu.statusBarHeight}px - 44px - 44px)`;
    					});
    				},
    				fail: (res) => {},
    			});
    		},
    		methods: {
    			hideMask() {
    				this.isFloorMask = false
    				this.isBuildingMask = false
    				this.isTableMask = false
    			},
    			initScrollTop(){
    				this.boardsInfo=[]
    				this.floorsList=[]
    				this.floorScrollTop=0
    				this.tableScrollTop=0
    				this.tableScrollLeft=0
    			},
    			// 获取项目下看板的信息
    			getBillBoardsList() {
    				this.initScrollTop()
    				uni.showLoading({
    					title:"加载中"
    				})
    				getBillBoardsList(this.projectId).then((responseData) => {
    					this.boardsInfo = responseData?.data?.data?.buildingUnitVOList;
    					uni.hideLoading() 
    					if (this.boardsInfo) {
    						this.floorsListHandler();
    					}
    				}).catch(()=>{
    					uni.hideLoading()
    				})
    			},
    			// 楼层数据汇总处理
    			floorsListHandler() {
    				this.floorsList = [];
    				const floorsList = [];
    				this.boardsInfo.forEach((boardInfo) => {
    					Object.keys(boardInfo.floorMap).forEach((floor) => {
    						if (floorsList.indexOf(floor) === -1) {
    							floorsList.push(floor);
    						}
    					});
    				});
    				setTimeout(() => {
    					this.floorScrollTop = 68 * this.floorsList.length + Math.random();
    					this.tableScrollTop = this.floorScrollTop;
    				}, 100);
    				this.floorsList = floorsList;
    			},
    			floorTouchstart() {
    				this.floorScrollFunc = true;
    				 
    				this.isBuildingMask = true
    				this.isTableMask = true
    			},
    			tableTouchstart() {
    				this.tableScrollFunc = true;
    				
    				this.isFloorMask = true
    				this.isBuildingMask = true
    			},
    			buildTouchstart() {
    				this.buildingScrollFunc = true;
    				
    				this.isFloorMask = true
    				this.isTableMask = true
    			},
    			floorScrollHandler(e) {
    				if (this.floorTimer) clearTimeout(this.floorTimer);
    				if (!this.floorScrollFunc) return;
    				this.floorTimer = setTimeout(() => {
    					this.floorScrollFunc = false;
    				}, 200);
    				const {
    					scrollTop
    				} = e.detail;
    				this.tableScrollTop = scrollTop;
    			},
    			tableScrollHandler(e) {
    				if (this.tableTimer) clearTimeout(this.tableTimer);
    				if (!this.tableScrollFunc) return;
    				this.tableTimer = setTimeout(() => {
    					this.tableScrollFunc = false;
    				}, 200);
    				const {
    					scrollTop,
    					scrollLeft
    				} = e.detail;
    				this.floorScrollTop = scrollTop;
    				this.buildingScrollLeft = scrollLeft;
    			},
    			buildingScrollHandler(e) {
    				if (this.buildingTimer) clearTimeout(this.buildingTimer);
    				if (!this.buildingScrollFunc) return;
    				this.buildingTimer = setTimeout(() => {
    					this.buildingScrollFunc = false;
    				}, 200);
    				const {
    					scrollLeft
    				} = e.detail;
    				this.tableScrollLeft = scrollLeft;
    			},
    		},
    	};
    </script>
    
    <style lang="scss" scoped>
    	.projectProgress {
    		height: 100%;
    		 100vw;
    		background-color: #ffffff;
    		border-top: 2rpx solid #dfdfdf;
    		box-sizing: border-box;
    
    		.floorsTable {
    			height: calc(100% - 196rpx);
    			background-color: #ffffff;
    			display: flex;
    			box-sizing: border-box;
    
    			.floors {
    				 174rpx;
    				min-height: 100%;
    				color: #333333;
    				font-size: 28rpx;
    				display: flex;
    				flex-direction: column-reverse;
    
    				.floorItem {
    					box-sizing: border-box;
    					height: 68rpx;
    					 100%;
    					text-align: center;
    					border-top: 2rpx solid #dfdfdf;
    					border-right: 2rpx solid #dfdfdf;
    					border-left: 2rpx solid #dfdfdf;
    					padding-top: 10rpx;
    				}
    			}
    
    			.allComponents {
    				display: flex;
    				flex-direction: row;
    				min- calc(100vw - 174rpx);
    				min-height: 100%;
    				flex-direction: column-reverse;
    
    				.componentTable {
    					display: flex;
    				}
    			}
    		}
    
    		.projectInfo {
    			height: 196rpx;
    			border: 2rpx solid #dfdfdf;
    			display: flex;
    			box-sizing: border-box;
    
    			.title {
    				height: 196rpx;
    				line-height: 170rpx;
    				background-color: #f8f8f8;
    				color: #333333;
    				font-size: 28rpx;
    				writing-mode: vertical-lr;
    				text-align: center;
    				z-index: 97;
    				letter-spacing: 8rpx;
    				border-right: 2rpx solid #dfdfdf;
    				box-sizing: border-box;
    			}
    
    			.buildingAndType {
    				display: flex;
    			}
    		}
    	}
    
    	.floor-mask {
    		position: fixed;
    		 174rpx;
    		height: 100vh;
    		left: 0;
    		bottom: 0;
    		top: 220rpx;
    		background-color: transparent;
    		z-index: 999999;
    	}
    
    	.building-mask {
    		position: fixed;
    		 100vw;
    		height: 196rpx;
    		left: 0;
    		right: 0;
    		bottom: 0;
    		background-color: transparent;
    		z-index: 999999;
    	}
    
    	.table-mask {
    		position: fixed;
    		 calc(100vw-174rpx);
    		height: calc(100vh-206px);
    		left: 174rpx;
    		right: 0;
    		bottom: 196rpx;
    		background-color:transparent;
    		z-index: 999999;
    	}
    </style>
    

      

  • 相关阅读:
    【翻译】让你的网站飞起来
    理解ASP.NET MVC中的模型绑定
    【转载】创建定制ASP.NET MVC视图引擎
    修改STM32主频
    Cortex系列ARM核心及体系结构介绍
    递归
    NFD模拟兴趣包的转发
    NX 笔记
    MicroPython 8266 配置
    Python JSON操作
  • 原文地址:https://www.cnblogs.com/daifuchao/p/16081914.html
Copyright © 2020-2023  润新知