uniapp使用scroll-into-view实现锚点定位和滚动监听功能【楼层效果 / 侧边导航联动效果】

大佬网址:

https://blog.csdn.net/weixin_47136265/article/details/132303570

效果

请添加图片描述

代码

<template><!-- 这里面有2个bug,已经解决,需要知道的地方1.methods里的scrollEvt(e)方法里面的  this.tabIndex = index != -1 ?  index : 0;2. 样式里面的.main 的height: calc(100vh - 300px);这个样式防止,分类滑动的时候,整体滑倒页面顶部bug,设置固定高度,就不会整体滑动到页面顶部了--><view class="max"><view class="box">123</view><view class="main"><scroll-view scroll-y="true" class="left-content"><view class="left-item" :class="{ 'activeItem': tabIndex == index }" v-for="(item,index) in leftData":key="item.id" @click="clickLeftItem(index)">{{item.title}}</view></scroll-view><scroll-view scroll-y="true" class="right-content" :scroll-into-view="scrollId" scroll-with-animation@scroll="scrollEvt"><view class="right-item" v-for="(item,index) in rightData" :key="item.id" :id="'item'+index"><view class="title">{{item.title}}</view><view class="content"><view class="content-item" v-for="itm in item.children" :key="itm.id">{{itm.text}}</view></view></view></scroll-view></view></view>
</template>
<script>export default {data() {return {tabIndex: 0,scrollId: '',distanceList: [],timer: null,isLeftClick: false,leftData: [{title: '第一个',id: 10001},{title: '第二个',id: 10002},{title: '第三个',id: 10003},{title: '第四个',id: 10004},{title: '第五个',id: 10005},{title: '第六个',id: 10006}],rightData: [{id: '20001',title: '第一部分标题',children: [{id: '30001',text: '第一个子项'},{id: '30002',text: '第二个子项'},{id: '30003',text: '第三个子项'},{id: '30004',text: '第四个子项'}]},{id: '20002',title: '第二部分标题',children: [{id: '30005',text: '第一个子项'},{id: '30006',text: '第二个子项'},{id: '30007',text: '第三个子项'}]},{id: '20003',title: '第三部分标题',children: [{id: '30008',text: '第一个子项'},{id: '30009',text: '第二个子项'},{id: '30010',text: '第三个子项'},{id: '30011',text: '第四个子项'}]},{id: '20004',title: '第四部分标题',children: [{id: '30012',text: '第一个子项'},{id: '30013',text: '第二个子项'}]},{id: '20005',title: '第五部分标题',children: [{id: '300014',text: '第一个子项'},{id: '300015',text: '第二个子项'}]},{id: '20006',title: '第六部分标题',children: [{id: '300016',text: '第一个子项'},{id: '300017',text: '第二个子项'},{id: '300018',text: '第三个子项'},{id: '300019',text: '第四个子项'}]}]}},mounted() {setTimeout(() => {this.getDistanceToTop();}, 500)},methods: {clickLeftItem(index) {this.isLeftClick = truethis.tabIndex = indexthis.scrollId = 'item' + index},getDistanceToTop() { //获取右侧各部分距离顶部的距离let that = thislet selectorQuery = uni.createSelectorQuery().in(this);selectorQuery.selectAll('.right-item').boundingClientRect(function(rects) {rects.forEach(function(rect) {that.distanceList.push(rect.top)})console.log('that.distanceList', that.distanceList);}).exec()},// 元素滚动到顶部时,对应的左侧导航栏变为选中状态scrollEvt(e) {// 点击左侧导航栏引起的滚动不做判断if (this.isLeftClick) {this.isLeftClick = falsereturn}// 防抖if (this.timer) {clearTimeout(this.timer)}this.timer = setTimeout(() => {let scrollTop = e.detail.scrollTop //滚动的高度// 找到位于顶部元素的索引,距离大于滚动高度的第一个元素的上一个元素就是此时位于顶部的元素let index = this.distanceList.findIndex(it => {// 滚动条的位置大于元素距离顶部位置的距离时,说明元素已经滑过了顶部return (it > scrollTop)}) - 1if (index == this.tabIndex) return// this.tabIndex = index;		// 这里是个	bugthis.tabIndex = index != -1 ? index : 0; //  修改后可以了正确了,找人花了我50大洋,五分钟解决,太厉害了!!!}, 200)}}}
</script>
<style lang="less" scoped>.max {display: flex;flex-direction: column;}.box {width: 100%;height: 200rpx;border: 1rpx solid red;}.main {display: flex;justify-content: space-between;width: 100vw;// 这里控制楼层高度,防止全部滑动到页面顶部,这里设置高度,这样设置!!!height: calc(100vh - 300px);// 或者用这个var(--status-bar-height) 是app的上面状态栏高度//height: calc(100vh - var(--status-bar-height) - 300rpx);//重点!!!margin-top: 100rpx;border: 1rpx solid red;}.left-content {width: 250rpx;height: 100%;background-color: #E7E7E7;}.left-item {width: 100%;height: 100rpx;text-align: center;line-height: 100rpx;}.activeItem {background-color: #fff;color: skyblue;}.right-content {flex: 1;height: 100%;background-color: #f4f4f4;}.content-item {width: 100%;height: 200rpx;background-color: aqua;margin-top: 20rpx;overflow:auto;//重点height: calc(100vh - var(--status-bar-height) - 300rpx);//重点!!!}.title {padding: 15px 0 0 10px;}// 去掉右部分有滚动条/deep/::-webkit-scrollbar {display: none;width: 0;height: 0;}
</style>

大佬

效果

请添加图片描述

代码

<template><view class="bodys"><view class="scroll_box" id="scroll_box"><scroll-view :style="{ height: scrollHeight + 'px' }" scroll-y='true' class="left_box":scroll-into-view="leftIntoView"><view class="left_item" v-for="(item,i) in leftArray" :key='i' @click="onLeft" :data-index="i":id="'left-'+i" :class="{select:i == leftIndex}">{{item}}</view></scroll-view><scroll-view :style="{ height: scrollHeight + 'px' }" @scroll="mainScroll" :scroll-into-view="scrollInto"scroll-y='true' class="right_box" scroll-with-animation="true"><slot></slot><view class="right_item" v-for="(item,i) in rightArray" :key='i' :id="'item-'+i"><view class="rigth_title">{{item.title}}</view><view class="lis" v-for="(items,j) in item.list" :key='j'>{{items}}</view></view><view class="fill-last" :style="{ height: fillHeight + 'px' }"></view></scroll-view></view></view>
</template><script>export default {name: "side-navigation",data() {return {leftArray: [],rightArray: [],scrollHeight: 400,scrollInto: "",leftIndex: 0,topArr: [],scrollTopSize: 0,fillHeight: 0, // 填充高度,用于最后一项低于滚动区域时使用}},computed: {/* 计算左侧滚动位置定位 */leftIntoView() {return `left-${this.leftIndex > 3 ? this.leftIndex - 3 : 0}`;}},mounted() {/* 等待DOM挂载完成 */this.$nextTick(() => {/* 在非H5平台,nextTick回调后有概率获取到错误的元素高度,则添加200ms的延迟来减少BUG的产生 */setTimeout(() => {/* 等待滚动区域初始化完成 */this.initScrollView().then(() => {/* 获取列表数据,你的代码从此处开始 */this.getListData();});}, 200);});},methods: {/* 初始化滚动区域 */initScrollView() {return new Promise((resolve, reject) => {let view = uni.createSelectorQuery().select('#scroll_box');view.boundingClientRect(res => {console.log(res);this.scrollTopSize = res.top;this.scrollHeight = res.height;this.$nextTick(() => {resolve();});}).exec();});},// 获取数据getListData() {new Promise((resolve, reject) => {uni.showLoading();setTimeout(() => {let [left, main] = [[],[]];for (let i = 0; i < 25; i++) {left.push(`${i + 1}类商品`);let list = [];let r = Math.floor(Math.random() * 10);r = r < 1 ? 3 : r;for (let j = 0; j < r; j++) {list.push(j);}main.push({title: `${i + 1}类商品标题`,list});}// 将请求接口返回的数据传递给 Promise 对象的 then 函数。resolve({left,main});}, 1000);}).then(res => {uni.hideLoading();this.leftArray = res.left;this.rightArray = res.main;// DOM 挂载后 再调用 getElementTop 获取高度的方法。this.$nextTick(() => {this.getElementTop();});});},// 获取元素顶部信息getElementTop() {new Promise((resolve, reject) => {let view = uni.createSelectorQuery().selectAll('.right_item');view.boundingClientRect(data => {resolve(data);}).exec();}).then(res => {console.log(res);let topArr = res.map(item => {return item.top - this.scrollTopSize; /* 减去滚动容器距离顶部的距离 */});this.topArr = topArr;/* 获取最后一项的高度,设置填充高度。判断和填充时做了 +-20 的操作,是为了滚动时更好的定位 */let last = res[res.length - 1].height;if (last - 20 < this.scrollHeight) {this.fillHeight = this.scrollHeight - last + 20;}});},// 点击左侧导航onLeft(e) {const index = e.currentTarget.dataset.index;// this.leftIndex = indexthis.scrollInto = `item-${index}`},// 右侧滑动mainScroll(e) {let top = e.detail.scrollTop;let index = 0;/* 查找当前滚动距离 */for (let i = this.topArr.length - 1; i >= 0; i--) {/* 在部分安卓设备上,因手机逻辑分辨率与rpx单位计算不是整数,滚动距离与有误差,增加2px来完善该问题 */if (top + 2 >= this.topArr[i]) {index = i;break;}}this.leftIndex = index < 0 ? 0 : index;},},}
</script><style>page,.bodys {height: 100%;}.scroll_box {display: flex;height: 100%;}.left_box {width: 30%;}.left_item {height: 80rpx;}.lis {height: 200rpx;border-radius: 10rpx;background: #808080;color: #FFFFFF;text-align: center;line-height: 200rpx;margin-bottom: 10rpx;}.select {background-color: #4CD964;}
</style>

Vant-UI官网

网址1

网址2

推荐uniapp插件市场

uniapp插件市场搜索商品分类!!!
好用,兼容性各个端,好用,我就用的这个插件!!!

地址

https://ext.dcloud.net.cn/plugin?id=13148

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145910.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL - DML数据增删改

功能介绍&#xff1a; DML&#xff08;Data Manipulation Language&#xff09;数据操作语言&#xff0c;用来对数据库中表的数据记录进 行增、删、改操作。 添加数据&#xff08;INSERT&#xff09; 基本语法&#xff1a;insert into 表名(字段列表) values (值列表); …

el-collapse 嵌套中 el-checkbox作为标题,选中复选框与el-tree联动

<el-drawertitle"应用授权":visible.sync"menuDrawer"><el-collapse accordion style"padding: 15px"><el-collapse-item v-for"item in platList"><template slot"title"><el-checkbox v-model…

Mysql各种锁

一.不同存储引擎支持的锁机制 Mysql数据库有多种数据存储引擎&#xff0c;Mysql中不同的存储引擎支持不同的锁机制 MyISAM和MEMORY存储引擎采用的表级锁 InnoDB存储引擎支持行级锁&#xff0c;也支持表级锁&#xff0c;默认情况下采用行级锁 二.锁类型的划分 按照数据操作…

postgresql-管理数据表

postgresql-管理数据表 创建表数据类型字段约束表级约束模式搜索路径 修改表添加字段删除字段添加约束删除约束修改字段默认值修改字段数据类型重命名字段重命名表 删除表 创建表 在 PostgreSQL 中&#xff0c;使用 CREATE TABLE 语句创建一个新表&#xff1a; CREATE TABLE …

深度学习笔记_1、定义神经网络

1、使用了PyTorch的nn.Module类来定义神经网络模型;使用nn.Linear来创建全连接层。(CPU) import torch.nn as nn import torch.nn.functional as F from torchsummary import summary# 定义神经网络模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()…

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…

std::initializer_list详解

std::initializer_list介绍 initializer_list是C11提供的一种新类型&#xff0c;其定义于头文件<initializer_list>中&#xff0c;此头文件是工具库的一部分&#xff0c; <initializer_list>定义如下&#xff1a; namespace std {template<class E> class…

ubuntu22.04使用共享文件设置

从ubuntu20.04开始&#xff0c;设置共享文件就很麻烦 第一步&#xff1a; 安装samba&#xff1a; sudo apt install samba第二步; 创建一个共享文件夹 我以桌面Desktop为例子 第三步&#xff1a; 设置密码&#xff1a; sudo smbpasswd -a ygc第四步&#xff1a; sudo vim …

Pikachu靶场——XXE 漏洞

文章目录 1. XXE1.1 查看系统文件内容1.2 查看PHP源代码1.3 查看开放端口1.4 探测内网主机 1. XXE 漏洞描述 XXE&#xff08;XML External Entity&#xff09;攻击是一种利用XML解析器漏洞的攻击。在这种攻击中&#xff0c;攻击者通过在XML文件中插入恶意实体来触发解析器加载…

亲测可用国产GPT人工智能

分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型&#xff0c;工作效率都会极大提升。 清华大学ChatGLM 官网&#xff1a; 智谱清言中国版对话语言模型&#xff0c;与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型&#xff0…

CSP-J第二轮试题-2020年-1.2题

文章目录 参考&#xff1a;总结 [CSP-J2020] 优秀的拆分题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示样例 1 解释数据规模与约定 答案1答案2 [CSP-J2020] 直播获奖题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 …

第80步 时间序列建模实战:GRNN回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们使用Matlab进行GRNN模型的构建。 使用的数据如下&#xff1a; 采用《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrom…

java web+Mysql e-life智能生活小区物业管理系统

本项目为本人自己书写&#xff0c;主要服务小区业主和管理人员。 e-life智能生活小区涉及多个方面的智能化和便利化服务&#xff1a; 1. 用户模块&#xff1a;包含基本的登入登出操作&#xff0c;查看个人信息中用户可以查看 自己的个人资料但不可以修改个人信息。 a) 用户…

PS 切片工具 选择切片 切片存储

上文 PS 透视裁剪工具 中 我们简单讲述了透视裁剪工具 今天 我们来讲他后面的切片工具 首先 他的用途还是很多的 例如 你有一个很大的图片 其中包括 轮播 导航 主题内容 但他们都在一个图片上 你就可以用切片工具 将完整的图片切成多个部分 这里 我们选择了切片工具 光标也会…

BUUCTF reverse wp 56 - 60

[ACTF新生赛2020]SoulLike __int64 __fastcall main(int a1, char **a2, char **a3) {char v5; // [rsp7h] [rbp-B9h]int i; // [rsp8h] [rbp-B8h]int j; // [rspCh] [rbp-B4h]int flag_content[14]; // [rsp10h] [rbp-B0h] BYREFchar flag[110]; // [rsp4Ah] [rbp-76h] BYREFu…

蓝桥等考Python组别九级008

第一部分&#xff1a;选择题 1、Python L9 &#xff08;15分&#xff09; 运行下面程序&#xff0c;可以输出几行“*”&#xff1f;&#xff08; &#xff09; for i in range(8): for j in range(9): print(*, end ) print() 78910 正确答案&#xff1a;B 2、Python…

maven无法下载时的解决方法——笔记

右键项目然后点击创建setting.xml&#xff08;因为现在创建了&#xff0c;所以没显示了&#xff0c;可以直接点击打开setting.xml&#xff09; 然后添加 <mirror><id>nexus-aliyun</id><mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf><name…

数据结构 图 并查集 遍历方法 最短路径算法 最小生成树算法 简易代码实现

文章目录 前言并查集图遍历方法广度优先遍历深度优先遍历 最小生成树算法Kruskal算法Prim算法 最短路径算法Dijkstra算法BellmanFord算法FloydWarshall算法 全部代码链接 前言 图是真的难&#xff0c;即使这些我都学过一遍&#xff0c;再看还是要顺一下过程&#xff1b;说明方…

【Window10 】删除‘设备和驱动器’中的百度网盘、酷狗音乐、迅雷下载等

原因&#xff1a; 不想在设备里看到它。 解决方案&#xff1a; 打开cmd找到 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\ 目录在 NameSpace 目录下找到对应的软件目录&#xff0c;删除即可&#xff08;挨个目录的点击进去看…

【Django 笔记】第一个demo

1. pip 安装 2. django 指令 D:\software\python3\anconda3\Lib\site-packages\django\bin>django-adminType django-admin help <subcommand> for help on a specific subcommand.Available subcommands:[django]checkcompilemessagescreatecachetabledbshelldiff…