小程序齐层看板 scroll-view 解决抖动

 

        

 

 

 

    这个图分解成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%; width: 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%; width: 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="width: 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%;
		width: 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 {
				width: 174rpx;
				min-height: 100%;
				color: #333333;
				font-size: 28rpx;
				display: flex;
				flex-direction: column-reverse;

				.floorItem {
					box-sizing: border-box;
					height: 68rpx;
					width: 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-width: 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;
		width: 174rpx;
		height: 100vh;
		left: 0;
		bottom: 0;
		top: 220rpx;
		background-color: transparent;
		z-index: 999999;
	}

	.building-mask {
		position: fixed;
		width: 100vw;
		height: 196rpx;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: transparent;
		z-index: 999999;
	}

	.table-mask {
		position: fixed;
		width: calc(100vw-174rpx);
		height: calc(100vh-206px);
		left: 174rpx;
		right: 0;
		bottom: 196rpx;
		background-color:transparent;
		z-index: 999999;
	}
</style>

  

posted @ 2022-03-31 15:05  福超  阅读(1028)  评论(0编辑  收藏  举报