vue实现导航里面锚点定位和滚动监听功能

需求

我们在开发过程中有时候会遇到左侧导航菜单栏数据需要监听和右侧顶部导航菜单联动效果。这里我们通常使用锚点定位和滚动监听方法实现。这里我们使用两种方案解决,第一是常规的出来方法,第二是通过uniapp里面的scroll-view进行处理

具体实现方案如下
一、vue里面处理,通过监听滚动事件和定义元素

1- 代码如下

<template><div><div class="outBox"><div class="first"><div :class="['level', {'select': i == first.select}]" style="background-color: #666;" v-for="(v, i) in first.list">{{ v }}</div></div><div class="second" id="select"><div :class="['level', {'select': i == second.select}]" style="background-color: #666;" v-for="(v, i) in second.list">{{ v }}</div></div><div class="content" id="content"><div v-if="status" class="box box1" style="height: 100px;">二级类目1 商品内容</div><div v-if="status" class="box box2" style="height: 344px;">二级类目2 商品内容</div><div v-if="status" class="box box3" style="height: 470px;">二级类目3 商品内容</div><div v-if="status" class="box box4" style="height: 230px;">二级类目4 商品内容</div></div></div></div>
</template>
<script>
export default {data() {return {first: {select: 0,list: ['一级类目1', '一级类目2', '一级类目3', '一级类目4',  '一级类目5']},second: {select: 0,list: ['二级类目1', '二级类目2', '二级类目3', '二级类目4']},list: [],timer: null,status: true}},methods: {scroll() {let scrollTop = document.getElementById('content').scrollToplet i = this.list.findIndex(v => v >= scrollTop)this.second.select = iif (scrollTop >= this.list[this.list.length - 1] - 20) {this.timer && clearTimeout(this.timer)this.timer = setTimeout(() => {this.second.select = 0this.first.select += 1document.getElementById('content').removeEventListener('scroll', this.scroll)document.getElementById('content').scrollTo(0, 10)document.getElementById('content').addEventListener('scroll', this.scroll)// 判断如果左侧导航菜单数据没有的情况默认选中定义导航菜单if (this.first.select >= this.first.list.length) {this.first.select = 0}}, 300)} else if (scrollTop == 0) {this.timer && clearTimeout(this.timer)this.timer = setTimeout(() => {this.second.select = 0if (this.second.select > 0) {this.first.select -= 1} else {// 滚动到顶部刷新数据this.first.select = 0}document.getElementById('content').removeEventListener('scroll', this.scroll)document.getElementById('content').scrollTo(0, 10)document.getElementById('content').addEventListener('scroll', this.scroll)}, 300)}}},mounted() {let o = document.getElementsByClassName('box')for ( let i = 0; i < o.length; i++) {// 监测右侧导航菜单距离顶部的距离60this.list[i] = i > 0 ? o[i-1].scrollHeight + this.list[i - 1] + (60 * (i > 1 ? 1 : 0)) : 10}let scrollHeight = document.getElementById('content').scrollHeightlet offsetHeight = document.getElementById('content').offsetHeightif (scrollHeight - offsetHeight < this.list[this.list.length - 1]) {this.list[this.list.length - 1] = scrollHeight - offsetHeight}document.getElementById('content').addEventListener('scroll', this.scroll)}
}
</script>
<style>
.outBox{width: 400px;height: 300px;margin: 0;padding: 0;background-color: #eee;position: relative;}.first{position: absolute;left: 0;top: 0;width: 100px;height: 100%;overflow: auto;background-color: rgb(102, 102, 102);}.first .level{height: 30px;font-size: 14px;text-align: center;line-height: 30px;}.second{position: absolute;left: 100px;top: 0;width: calc(100% - 100px);height: 60px;overflow: auto;background-color: #06c;display: flex;align-items: center;justify-content: space-around;}.second .level{height: 30px;font-size: 14px;text-align: center;line-height: 30px;}.content{position: absolute;left: 100px;top: 60px;width: calc(100% - 100px);height: calc(100% - 60px);min-height: 240px;overflow: auto;box-sizing: border-box;}.box{background-color: aquamarine;margin-bottom: 20px;}.select{color: #f56c6c;}
</style>

2- 实现结果如下:

在这里插入图片描述
在这里插入图片描述

二、uni-app使用scroll-view锚点定位和滚动监听功能

1- 代码如下
html

<template><view class="classicsBox"><scroll-view class="classics-left" scroll-y="true" scroll-with-animation :scroll-into-view="clickId"><view v-for="(item,index) in contentData" :key="item.id" :id="item.id" class="classics-left-item" :class="picked==index?'checkedStyle':''" @click="selectActiveEvt(item)">{{item.title}}</view></scroll-view><!-- :scroll-top="scrollRightTop" --><scroll-view scroll-y="true"  :scroll-into-view="clickId" :scroll-anchoring="true" scroll-with-animation class="classics-right" @scroll="scrollEvt"><view class="classics-right-item" v-for="item in contentData" :key="item.id" :id="item.id"><view class="title">{{item.title}}</view><view class="item-box" v-for="it in item.content"><img class="item-box-left" :src="it.img" alt=""><view class="item-box-right"><view class="item-box-right-name">{{it.name}}</view><view class="item-box-right-describe">{{it.desc}}</view><view class="item-box-right-buy"><view class="item-box-right-price">{{it.price}}</view><view class="item-box-right-pick">选规格</view></view></view></view></view></scroll-view></view>
</template>

js

<script>export default {components: {},data() {return {contentData:[{id:'tab1',title:'热销专区',content:[{id:101,img:'static/rexiao1.png',name:'郁金香',desc:'花语',price:'99',},{id:102,img:'static/rexiao2.png',name:'郁金香',desc:'花语',price:'99',},]},{id:'tab2',title:'生日鲜花',content:[{id:201,img:'static/shengri1.png',name:'郁金香',desc:'花语',price:'99',},{id:202,img:'static/shengri2.png',name:'郁金香',desc:'花语',price:'99',},]},......],//列表数据clickId:'tab1', //点击选项的idpicked:0, // 左侧选中选项的indexnowRightIndex:0, // 右边当前滚动的indexitemArr:[], //用于存放右侧item位置数据scrollRightTop:0,timer:null,}},methods: {// 左侧切换点击事件selectActiveEvt(e) {this.clickId = e.id;this.picked = this.contentData.findIndex(it=>it.id==e.id);},scrollEvt(e){// 防抖if(this.timer){clearTimeout(this.timer);}this.timer = setTimeout(()=>{this.nowRightIndex =  this.itemArr.findLastIndex(it=>e.detail.scrollTop>=(it.bottom-228))+1; //判断当前顶部是处于哪个item,获取当前item的indexif(this.nowRightIndex==-1) this.nowRightIndex=0;if(this.nowRightIndex==this.picked) return;this.clickId = this.contentData[this.nowRightIndex].id;this.picked = this.nowRightIndex;},500);},// 计算右侧每个item到顶部的距离,存放到数组getItemDistence(){new Promise(resolve=>{let selectQuery = uni.createSelectorQuery().in(this);selectQuery.selectAll('.classics-right-item').boundingClientRect(rect=>{if(!rect.length){setTimeout(()=>{this.getItemDistence();},10);return;}rect.forEach(it=>{this.itemArr.push(it); // 这里获取到的数据是每个item距离页面顶部的数据,以及每个item的自身数据resolve();})}).exec()})},},mounted(){// 设置一个延时,确保所有dom和样式加载完成,否则拿到的数据可能有误setTimeout(()=>{this.getItemDistence();},500)},}
</script>

css

	.sortBox{height: 100%;width: 100%;box-sizing: border-box;/* padding: 12px; */padding-bottom: 0;position: relative;}.boxTop{width: 100%;position: fixed;top: 44px;left: 0;height: 220px;}.sort-search{height: 50px;display: flex;justify-content: space-between;padding: 12px;padding-bottom: 0;box-sizing: border-box;}.sort-search-left{box-sizing: border-box;width: 100px;height: 38px;line-height: 38px;border-radius: 16px;border: 1px solid #f0f0f0;text-align: right;padding: 0 10px;background: url('../../static/ping.png') left center no-repeat;background-size: 45%;}.sort-search-right{width: 36px;height: 100%;margin-right: 80px;border: #f0f0f0 1px solid;border-radius: 19px;text-align: center;line-height: 36px;}.sort-collect{margin-top: 15px;}.sort-broadcast{width: 100%;height: 30px;background-color: #fff7fa;display: flex;font-size: 18px;line-height: 30px;padding: 0 10px;box-sizing: border-box;font-weight: bold;}.sort-type{display: flex;height: 60px;box-sizing: border-box;align-items: flex-end;justify-content: space-evenly;font-size: 16px;font-weight: bold;color: #909090;}.sort-type-item{display: flex;align-items: center;height: 40px;}.sort-type-item-img{height: 30px;margin-right: 6px;}.sort-type-item-text{height: 100%;line-height: 40px;}.sort-type-item-text-checked{border-bottom: #ff9092 3px solid;color: #41414d;}.opcity{opacity: 0;}.sortBox-scoll{position: absolute;top: 220px;left: 0;width: 100%;background-color: #f0f0f0;height: calc(100vh  - 314px);overflow-y: auto;}

2- 实现结果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库管理-第132期 该如何成为一个合格的DBA(20240112)

数据库管理132期 2024-01-12 第132期 该如何成为一个合格的DBA&#xff08;20240112&#xff09;1 路线2 心态3 本质总结 第132期 该如何成为一个合格的DBA&#xff08;20240112&#xff09; 去年总结的时候&#xff0c;把最后一个活动搞丢了&#xff0c;【ACDU分享会】DBA的危…

微软等开源评估ChatGPT、Phi、Llma等,统一测试平台

微软亚洲研究院、中国科学院自动化研究所、中国科学技术大学和卡内基梅隆大学联合开源了&#xff0c;用于评估、分析大语言模型的统一测试平台——PromptBench。 Prompt Bench支持目前主流的开源、闭源大语言模型&#xff0c;例如&#xff0c;ChatGPT、GPT-4、Phi、Llma1/2、G…

Android音频框架之一 详解audioPolicy流程及HAL驱动加载与配置

一、 AndroidRuntime.so 引发思考 android 系统 framework 代码起点, frameworks/base/core/jni/AndroidRuntime.cpp 文件&#xff0c; 此文件是android系统主线程代码&#xff0c;代码内容涉及系统很多模块&#xff0c;此程序主要是注册模块的JNI接口方法。其中涉及到模块 na…

使用pandas按照商品和下单人统计下单数据

目录 一&#xff1a;需求描述 二&#xff1a;代码实现 三&#xff1a;注意事项 一&#xff1a;需求描述 最近运营那边给到一个excel表格&#xff0c;是一个小程序用户的下单数据&#xff0c;要以商品为维度&#xff0c;统计用户下单情况&#xff0c;主要是下单的商品总金额&…

两周掌握Vue3(四):计算属性、监听属性、事件处理

文章目录 一、计算属性1.什么是计算属性2.代码示例 二、监听属性三、事件处理 代码仓库&#xff1a;跳转 当前分支&#xff1a;04 一、计算属性 1.什么是计算属性 Vue 中的计算属性具有以下作用&#xff1a; 数据处理&#xff1a;计算属性可以用于对数据进行处理和计算&…

开源笔记工具AFFiNE本地部署并结合内网穿透

前言 本篇文章讲解Notion开源平替全能知识库工具AFFINE如何本地部署&#xff0c;并实现公网远程访问。AFFiNE 是一个全新的开源项目&#xff0c;旨在克服 Notion 和 Miro 在安全和隐私方面的一些局限性。它的设计目标是帮助用户将会议记录、待办事项、文档中的目标、视频会议白…

如何运用自养号测评策略在Lazada、Shopee上轻松提升销售和排名

卖家们常常会为Lazada、Shopee店铺销量不佳而感到困惑。然而&#xff0c;仅仅感叹并不能解决问题。作为卖家&#xff0c;我们需要深入分析问题&#xff0c;并采取有效的措施来解决它们。基本功是提升销量的基石&#xff0c;但仅仅依靠基本功是不够的。我们需要将运营和测评结合…

【Java】正则表达式( Pattern 和 Matcher 类)

快速入门 Java 提供了 java.util.regex 包&#xff0c;它包含了 Pattern 和 Matcher 类&#xff0c;用于处理正则表达式的匹配操作。 java.util.regex 包主要包括以下三个类&#xff1a; Pattern 类&#xff1a; pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共…

程序员必知!组合模式的实战应用与案例分析

组合模式是一种设计模式&#xff0c;允许将对象组合成树形结构并像单个对象一样使用它们&#xff0c;这种模式在处理类似公司组织结构这样的树形数据时非常有用&#xff0c;通过组合模式&#xff0c;我们可以将公司和部门视为同一类型的对象&#xff0c;从而以统一的方式处理发…

SV-9001 壁挂式网络采播终端

SV-9001 壁挂式网络采播终端 一、描述 SV-9001是深圳锐科达电子有限公司的一款壁挂式网络采播终端&#xff0c;具有10/100M以太网接口&#xff0c;配置一路线路输入和一组麦克风输入&#xff0c;可以直接连接音源输出设备或麦克风&#xff0c;将采集音源编码后发送至网络播放终…

仲晶同志简历

女&#xff0c;汉族。1972年出生&#xff0c;国防大学科技与装备教研室教官。1992年&#xff0c;仲晶毕业于军事气象学院&#xff0c;1996年成为国防大学国防科技发展战略学硕士研究生&#xff0c;毕业后留校任教。曾出版过9部军事专著&#xff0c;先后发表学术论文100多万字。…

CANoe中最常见的文件类型

文件类型图标说明文件说明保存步骤附加说明example.cfg此文件相当于一个集成的可执行文件&#xff0c;双击该图标就能打开工程Flie-》savepanel.xvp是vxp&#xff0c;控制盘文件home界面。打开panel 图标。在专门编辑界面保存。trace界面 导出的报文 报文存在多种格式&#xff…