目录
1、html部分
- 1、html部分
- 2、JavaScript部分
- 3、css部分
<template> <view> <view class="left_right_column_box"> <view class="left_column"> <scroll-view :style="{height: viewHeight}" scroll-y="true" :scroll-top="scrollTop"> <view v-for="item in titleContenData" :key="item.id" :class="{'left_column_for': true, activity: selectIndex==item.index?true:false}" @click="clickTitle(item)"> {{item.title}} {item.title}}{items.content}} data() { return { // 屏幕高度 viewHeight: null, // 源数据 titleContenData: [], // 设置锚点 selectId: 'id1', // 设置高亮 selectIndex: 0, // 设置左栏顶部距离 scrollTop: 0, } }, mounted() { let that = this; uni.getSystemInfo({ success: function({ windowHeight }) { that.viewHeight = windowHeight + 'px'; } }); // 创建数据 that.createData(); // 此处使用$nextTick是非常有必要 // 官方建议 // 实际测试如果不用会报错 that.$nextTick(function() { const query = uni.createSelectorQuery().in(that); query.selectAll('.floorType').boundingClientRect(VNodeAll => { VNodeAll.forEach(({ top }, i) => { // 获取并存储每个视图到顶部的距离 this.titleContenData[i].viewTop = top; }); }).exec(); console.log('titleContenData:', this.titleContenData); }); }, methods: { // 滚动时触发 scroll({ detail: { scrollTop } }) { let that = this, titleContenData = that.titleContenData; // 防抖 // timer定义在全局 // 如果没有防抖会触发许多次 // 对性能不友好 if (timer !== undefined) clearTimeout(timer); timer = setTimeout(function() { // 当右侧滚动到顶部时强制赋值为0 // 因为在滚动时一般获取到的数据是0-10的范围 // 小概率会获取到0 // 因为原先存储viewTop属性的第一个值就是0 scrollTop = scrollTop < 10 ? 0 : scrollTop; let selectIndex = titleContenData.findIndex((item) => item.viewTop >= scrollTop); console.log('scrollTop:', scrollTop); // 设置高亮 that.selectIndex = selectIndex; // 此属性联动左侧滚动条 // 当右侧滚动时 // 左侧也会相应的滚动 // 只是滚动的距离不一样 that.scrollTop = 5 * that.selectIndex; }, 70); }, // 标题点击事件 clickTitle({ id, index }) { console.log(id, index); // 设置锚点 this.selectId = id; // 设置高亮 this.selectIndex = index; }, // 生成内容 createContent(n) { let content = []; for (let i = 0; i < n; i++) content.push({ id: i + 1, content: `内容${i+1}内容` }); return content; }, // 创建数据 createData() { // 生成标题 for (let i = 0; i < 24; i++) this.titleContenData.push({ // 因为需要绑定id作为锚点目标 // 所以不能以数字开头 id: `id${i+1}`, index: i, title: '标题' + (i + 1), contents: this.createContent(parseInt(Math.random() * 24 + 1, 10)) }) } }, }3、css部分
/* 公共样式 */ .left_right_column_box { width: 100%; display: flex; justify-content: space-evenly; } /* 左侧样式 */ .left_column { flex: 1; } .left_column_for { text-align: center; padding: 10rpx 0; } .activity { color: #000fff; } /* 右侧样式 */ .right_column { flex: 3; margin-left: 36rpx; } .right_title_content_for { margin-top: 36rpx; } .right_title_content_for:first-child { margin-top: 0; } .right_title { font-weight: 700; } /* 隐藏scroll-wiew元素的滚动条 */ scroll-view ::-webkit-scrollbar { width: 0; height: 0; background-color: transparent; }