uniapp实现仿京东左右联动活动(商品分类)

第一步,页面布局


		
			
				
					{{item.name}}
				
			
			
				
					
						
							{{item.name}}
						
						
							
								
								{{item1.name}}
							
						
					
					
				
			
		
	

第二步:css部分,这里就自己写了,按照自己的项目效果图自己调一下效果

第三步:js部分

1、

data() {
			return {
				scrollTop: 0, //tab标题的滚动条位置
				oldScrollTop: 0, // tab标题的滚动条旧位置
				current: 0, // 预设当前项的值
				menuHeight: 0, // 左边菜单的高度
				menuItemHeight: 0, // 左边菜单item的高度
				itemId: '', // 栏目右边scroll-view用于滚动的id
				scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
				arr: [], // 储存距离顶部高度的数组
				timer: null, // 定时器
				flist: [], //左侧一级分类
				slist: []  //右侧一级+二级分类,构造可以嵌套的数组结构

			}
		},

2、点击左侧分类事件

/**
			* 点击左边的栏目切换
			* @index 传入的 ID
			*/
			async swichMenu(index) {
				if(this.arr.length == 0) {
					await this.getMenuItemTop();
				}
				if (index == this.current) return;
				this.scrollRightTop = this.oldScrollTop;
				this.$nextTick(function(){
					this.scrollRightTop = this.arr[index];
					this.current = index;
					this.leftMenuStatus(index);
				})
			},

3、右侧滑动事件

 

async rightScroll(e) {
					this.oldScrollTop = e.detail.scrollTop;
					if(this.arr.length == 0) {
						await this.getMenuItemTop();
					}
					if(this.timer) return ;
					if(!this.menuHeight) {
						await this.getElRect('menu-scroll-view', 'menuHeight');
					}
					setTimeout(() => { // 节流
						this.timer = null;
						// scrollHeight为右边菜单垂直中点位置
						// let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
						// scrollHeight为右边菜单头部位置
						let scrollHeight = e.detail.scrollTop + 20;
						for (let i = 0; i < this.arr.length; i++) {
							let height1 = this.arr[i];
							let height2 = this.arr[i + 1];
							if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
								this.leftMenuStatus(i);
								return ;
							}
						}
					}, 10)
			},

4、页面初始化时,获取右边每个节点距离顶部的高度,主要用于判断是否滑动,比如右边数据比较少的时候就不会在滑动

onReady() {
	this.getMenuItemTop()	
},


getMenuItemTop() {
			  	new Promise(resolve => {
			  		let selectorQuery = uni.createSelectorQuery();
			  		selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
			  			// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
			  			if(!rects.length) {
			  				setTimeout(() => {
			  					this.getMenuItemTop();
			  				}, 10);
			  				return ;
			  			}
			  			rects.forEach((rect) => {
			  				// 视情况而定,这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
			  				// this.arr.push(rect.top - rects[0].top);
			  				this.arr.push(rect.top)
			  				resolve();
			  			})
			  		}).exec()
			  	})
			},

5、基础功能函数

/**
			* 观测元素相交状态
			* 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
			* 如果跟.right-box底部相交,就动态设置左边栏目的活动状态
			*/
			async observer() {
				this.tabbar.map((val, index) => {
					let observer = uni.createIntersectionObserver(this);
					observer.relativeTo('.right-box', {
						top: 0
					}).observe('#item' + index, res => {
						if (res.intersectionRatio > 0) {
							let id = res.id.substring(4);
							this.leftMenuStatus(id);
						}
					})
				})
			},
			/**
			* 设置左边菜单的滚动状态
			* @index 传入的 ID
			*/
			async leftMenuStatus(index) {
				this.current = index;
				// 如果为0,意味着尚未初始化
				if (this.menuHeight == 0 || this.menuItemHeight == 0) {
					await this.getElRect('menu-scroll-view', 'menuHeight');
					await this.getElRect('u-tab-item', 'menuItemHeight');
				}
				// 将菜单活动item垂直居中
				this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
			},

/**
			* 获取一个目标元素的高度
			* @elClass 元素的类名
			* @dataVal 储存高度的对象
			*/
			getElRect(elClass, dataVal) {
					new Promise((resolve, reject) => {
						const query = uni.createSelectorQuery().in(this);
						query.select('.' + elClass).fields({
							size: true
						}, res => {
							// 如果节点尚未生成,res值为null,循环调用执行
							if (!res) {
								setTimeout(() => {
									this.getElRect(elClass);
								}, 10);
								return;
							}
							this[dataVal] = res.height;
							resolve();
						}).exec();
					})
			},

主要是uniapp操作dom节点的时候不是很方便,核心的实现原理其实跟jq一样 

 

 

 

 

你可能感兴趣的:(uniapp,java,前端,servlet)