先看看最终效果吧

在这里插入图片描述

背景:页面动态加载tab,tab里动态加载列表,上方有一块固定内容(个人资料)。

需求:判断未勾选节点,可自动跳转到目标节点处。

实现逻辑:将页面滚动到目标节点距离 = 指定节点离页面顶部的距离 + 页面在垂直方向已滚动的距离 - 内容列表上方固定区域高度

赋代码,无关代码已删除,仅供参考。
关键代码在:BindCreateDayLZRecord() 提交方法中。

<template>
	<view class="fullheight">
		<!-- 标题栏开始 -->
		<uni-nav-bar :fixed="true" :shadow="false" :border="false" :status-bar="true" left-icon="arrowthinleft" right-icon=""
		 right-text="记录" left-text="" title="页面标题" color="#343938" background-color="#ffffff" @clickLeft="BindGoBack"
		 @clickRight="BindGolzRecordList">
		</uni-nav-bar>
		<!-- 标题栏结束 -->

		<!-- 头部开始 -->
		<view class="padding-lr-sm padding-bottom-sm padding-top-sm bg-white headbox fullwidth">
			<!-- 用户资料开始 -->
			<view class="flex flex-wrap-nowrap justify-center align-center">
				<view class="headimg flex-sub">
					<image class="" mode="widthFix" src="/static/img/homeIndex/head.png"></image>
				</view>
				<view class="flex-twice">
					<view class="text-bold text-xl">王小明</view>
					<view class="text-sm text-gray">110</view>
				</view>
				<view class=" text-lg cu-list padding-right-sm flex flex-direction-column">
					<view class="text-lg bg-orange box-shadow right padding-lr-sm round ">
						人工
					</view>
					<view class="text-lg bg-green box-shadow right padding-lr-sm round margin-tb-sm">
						智能
					</view>
				</view>
			</view>
			<!-- 用户资料结束 -->
		</view>
		<!-- 头部结束 -->

		<!-- tab菜单开始 -->
		<view class="tabbox  bg-white fullwidth text-center box-border">
			<scroll-view scroll-x class="navtab nav  bg-white ">
				<view class="cu-item text-lg padding-xl " v-for="(TabItem,TabIndex) in TabList" :key="TabIndex" @tap="BindTabSelect"
				 :data-id="TabIndex" :class="TabIndex==TabCur?' text-orange cur':'text-gray'">
					{{TabItem}}
				</view>
			</scroll-view>
		</view>
		<!-- tab菜单结束 -->

		<!-- 内容开始 -->
		<view class="margin-bottom-sm hastop">
			<block v-for="(TabItem, TabIndex) in TabList.length" v-if="TabCur==TabIndex">
				<view class="fullwidth text-center padding-top-lg"><a href="javascript:void(0)" class="text-orange" @tap="BindGetLZDayAIResultInfo">加载检查结果</a></view>
				<!-- 进度条开始 -->
				<view class="listbox padding-lr-lg  margin-bottom-xl">
					<scroll-view scroll-y class="listboxscroll">
						<view class="box-shadow bg-white" v-for="(LZItemItem, LZItemIndex) in LoadList[TabIndex].Content" :key="LZItemItem.DayLZItemID"
						 :data-id="LZItemItem.DayLZItemID" :id="'LZ'+LZItemItem.DayLZItemID" :class="LZItemItem.WarningLineCss">
							<uni-section class="text-white" :class="LZItemItem.HasAI?'bg-green':'bg-orange'" :title="LZItemItem.Title" type=""></uni-section>
							<uni-collapse ref="add" class="warp" @change="">
								<uni-collapse-item :open="false" :show-animation="true" :showRadio="LZItemItem.HasCheck==1" :trueRadio="LZItemItem.HasCheckNormal==1"
								 :falseRadio="LZItemItem.HasCheckNormal==0" title="请补充内容" @change="BindRadioButtonChange($event,LZItemIndex)">
									<view class="cu-form-group solid-top" v-for="(ExtraItemItem, ExtraItemIndex) in LZItemItem.LZItemExtraItemList"
									 :key="ExtraItemItem.DayLZItemExtraItemID" :data-id="ExtraItemItem.DayLZItemExtraItemID">
										<view class="title">{{ExtraItemItem.Title}}</view>
										
									</view>
								</uni-collapse-item>
							</uni-collapse>
						</view>
					</scroll-view>
				</view>
				<!-- 进度条结束-->
				<button class="cu-btn block lg submitbtn round margin-lg shadow bg-white " @tap="BindCreateDayLZRecord">
					<text class="cuIcon-roundcheckfill margin-right-xs  "></text> <text class="">提交</text>
				</button>
			</block>
		</view>
		<!-- 内容结束 -->

		<w-picker :visible.sync="ShowDateTime" mode="date" startYear="2020" endYear="2030" value="" :current="true" fields="minute"
		 @confirm="BindDateTimeConfirm" @cancel="" :disabled-after="false" :ref="TabCur"></w-picker>

	</view>
</template>

<script>
	import AlphaMS from '@/static/js/AlphaMS.js';
	import wPicker from "@/components/w-picker/w-picker.vue"
	import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue'
	import uniCollapse from '@/components/uni-collapse/uni-collapse.vue'
	import uniCollapseItem from '@/components/uni-collapse-item/uni-collapse-item.vue'
	export default {
		components: {
			uniNavBar,
			uniCollapse,
			uniCollapseItem
		},
		data() {
			return {
				//内容列表上方固定区域高度 方便报错的时候页面滚动到指定位置
				TopHeight: 0,
				//页面在垂直方向已滚动的距离
				PageScrollTo: 0,
				//Tab列表
				TabList: ['营业前', '营业期间', '营业终了'],
				//Tab下标
				TabCur: 0,
				//加载内容列表
				LoadList: [],

			};
		},
		onLoad(options) {
			let Container = this;
			//用户验证
			AlphaMS.JSToolkit.HBApp.NeedLogin(this.InitLoad);
		},
		onReady() {
			let Container = this;
			//获取内容列表上方固定区域高度 方便报错的时候页面滚动到指定位置
			Container.GetTopHeight();
		},
		//监听页面滚动
		onPageScroll(res) {
			let Container = this;
			//页面在垂直方向已滚动的距离
			Container.PageScrollTo = res.scrollTop;
		},
		methods: {
			//初次加载
			InitLoad() {
				let Container = this;
				//获取每日履职记录履职项列表
				Container.GetDayLZRecordLZItemList();
			},
			//tab菜单改变事件
			BindTabSelect(event) {
				let Container = this;
				this.TabCur = event.currentTarget.dataset.id;
				//是否第一次加载 加载过以后就不再加载了
				if (!Container.LoadList[Container.TabCur].IsFirst) {
					return false;
				}
				//获取每日履职记录履职项列表
				Container.GetDayLZRecordLZItemList();
			},
			//获取每日履职记录履职项列表
			GetDayLZRecordLZItemList() {
				let Container = this;
				AlphaMS.JSToolkit.NET.BLRequest({
					Debug: true,
					FunctionRouteName: "xxxxx方法名",
					BLRequestObject: {
						//请求参数
						//类型 1:Before:营业前 2:Between:营业期间 3:After:营业终了
						Type: parseInt(Container.TabCur) + 1
					},
					BLResponse: {
						Success: (MyResponseObject) => {
							switch (MyResponseObject.ResultCode) {
								case 1:
									//是否第一次加载 加载过以后就不再加载了
									Container.LoadList[Container.TabCur].IsFirst = false;
									//每日履职记录履职项列表
									Container.LoadList[Container.TabCur].Content = MyResponseObject.DayLZRecordLZItemList;
									break;
								default:
									AlphaMS.JSToolkit.Dialog.OKBox(MyResponseObject.ResultMessage, function() {});
									break;
							}
						}
					}
				})
			},
			//绑定履职项是否检查正常 - 单选检查按钮改变事件
			BindRadioButtonChange(event, LZItemIndex) {
				let Container = this;
				
				//隐藏红色外框警示框线
				Container.LoadList[Container.TabCur].Content[LZItemIndex].WarningLineCss = "";
			},
			//提交
			BindCreateDayLZRecord() {
				let Container = this;
				//每日履职记录
				let DayLZRecordLZItemList = Container.LoadList[Container.TabCur].Content;
				//是否检查通过
				let CheckSuccess = true;

				//是否有未勾选履职项
				for (let i = 0; i < DayLZRecordLZItemList.length; i++) {
					//HasCheck : 是否需要检查结果 (页面上需不需要展示勾选框)
					//HasCheckNormal : 是否检查正常 1:正常 0:异常
					if (DayLZRecordLZItemList[i].HasCheck && DayLZRecordLZItemList[i].HasCheckNormal == -1) {
						//是否检查通过
						CheckSuccess = false;
						AlphaMS.JSToolkit.Dialog.OKBox("第” " + (i + 1) + " “项未勾选", function() {
							//根据ID查找标签
							uni.createSelectorQuery().select("#LZ" + DayLZRecordLZItemList[i].DayLZItemID).boundingClientRect(function(res) {
								//滚动到未勾选的标签指定位置 将页面滚动到目标位置
								uni.pageScrollTo({
									//指定节点离页面顶部的距离 + 页面在垂直方向已滚动的距离 - 内容列表上方固定区域高度
									scrollTop: res.top + Container.PageScrollTo - Container.TopHeight,
									duration: 100
								});

							}).exec(function() {
								//显示警示框线
								DayLZRecordLZItemList[i].WarningLineCss = "solid";
							});
							return false;
						});
						break;
					}
				}

				//检查未通过
				if (!CheckSuccess) {
					return false;
				}

				AlphaMS.JSToolkit.Dialog.MessageBox("是否提交履职", function() {
				//提交方法
				}, function() {});
			},
			
			//获取内容列表上方固定区域高度 方便报错的时候页面滚动到指定位置
			GetTopHeight() {
				let Container = this;
				//赋过值就不再重复获取了
				if (Container.TopHeight > 0)
					return false;

				//根据class查找标签
				uni.createSelectorQuery().select(".hastop").boundingClientRect(function(res) {
					//内容列表上方固定区域高度 方便报错的时候页面滚动到指定位置
					//这里+5 是留点空隙 不会死死贴着顶部
					Container.TopHeight = res.top + 5;
				}).exec();

			},
			//返回 如果是最后一页就到首页
			BindGoBack() {
				//返回
				getApp().GoBack();
			},
			
		}
	}
</script>

<style>
	page {
		background-color: #f6f8fa;
	}

	.cu-form-group+.cu-form-group {
		border: none;
	}

	/* 头部样式开始 */
	.headbox {
		z-index: 998;
		position: fixed;
		height: 200rpx;
	}

	.headimg image {
		width: 80%;
		height: 80%;
		border: 5rpx solid #fff;
	}

	.cu-tag.sm {
		padding: 10rpx;
	}


	/* 头部样式结束 */

	/* 头部开始 */
	/* tab菜单栏开始 */
	.tabbox {
		z-index: 998;
		height: 80rpx;
		margin-top: 200rpx;
		position: fixed;
	}

	/* tab菜单栏结束 */
	/* 头部结束 */


	/* 内容列表开始 */

	.listbox {
		margin-bottom: 20%;
	}

	.box-shadow {
		border-left: 1px solid #e6e6e6;
		border-right: 1px solid #e6e6e6;
	}

	.uni-section {
		margin-top: 30rpx;
	}

	.hastop {
		margin-top: 280rpx;
	}

	.nav .cu-item {
		width: 33.3%;
		height: 80rpx;
		line-height: 80rpx;
		margin: 0px;
	}

	.cu-card.article>.cu-item {
		padding-bottom: 0px;
	}

	.cu-card>.cu-item {
		margin: 10px 15px;
	}

	/* 警示框 */
	.solid::after {
		border: 10rpx solid rgba(255, 0, 0, 0.9);
		box-shadow: 20rpx 20rpx 20rpx rgba(255, 128, 127, .8);
	}

	/* 内容列表结束 */

	/* 按钮开始 */
	.submitbtn {
		margin-left: 20%;
		width: 60%;
		position: fixed;
		bottom: 10rpx;
	}

	/* 按钮结束 */
</style>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐