vue横向导航条滚动到顶部固定同时瞄点对应内容(copy即用)
这里监听window 的
scroll实现一个页面滚动,导航菜单定位,内容联动的一个简单组件,结合一些案例,按需进行了整合,在此记录一下
效果图如下
|
|
|
具体实现如下
一、先创建一个NavigateTool.vue导航组件
html
<template>
<div class="searchBar navigate__bar">
<ul :class="searchBarFixed == true ? 'isFixed' :''">
<li :class="{active: navIndex===0}" @click="scrollTo(0)">区域</li>
<li :class="{active: navIndex===1}" @click="scrollTo(1)">国界</li>
<li :class="{active: navIndex===2}" @click="scrollTo(2)">宇宙</li>
<li :class="{active: navIndex===3}" @click="scrollTo(3)">银河</li>
</ul>
</div>
</template>
js
1、mounted()中 监听页面滚动
mounted() {
// 监听滚动事件
window.addEventListener('scroll', this.onScroll, false)
},
2、 destroy() 中注销监听
destroy() {
// 必须移除监听器,不然当该vue组件被销毁了,监听器还在就会出错
window.removeEventListener('scroll', this.onScroll)
},
3、data挂载当前激活导航id
data(){
return{
navIndex:0,
searchBarFixed:false,
}
},
4、methods中添加 监听页面滚动事件方法
/**
* 页面滚动事件监听
*/
onScroll() {
// 获取所有锚点元素
const navContents = document.querySelectorAll('.home__content_comp div')
console.log(navContents.length)
// 所有锚点元素的 offsetTop
const offsetTopArr = []
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop)
})
// 获取当前文档流的 scrollTop
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义当前点亮的导航下标
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
// 如果 scrollTop 大于等于第n个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
// 那么此时导航索引就应该是n了
if (scrollTop >=offsetTopArr[n]) {
navIndex = n+1
}
}
navIndex = navIndex >= navContents.length? navIndex-1:navIndex;
console.log(navIndex)
this.navIndex = navIndex
// 组件吸附顶部
var offsetTop = document.querySelector('.navigate__bar').offsetTop;
if (scrollTop > offsetTop) {
this.searchBarFixed = true;
} else {
this.searchBarFixed = false;
}
},
5、methods中添加导航菜单点击事件(计算页面滚动位置与组件距离顶部距离)
/**
* 跳转到指定索引的元素
* @param index
*/
scrollTo(index) {
// 获取目标的 offsetTop
// css选择器是从 1 开始计数,我们是从 0 开始,所以要 +1
// const foundEl = document.querySelector(`.home__content_comp div:nth-child(${index + 1})`);
// const elClientHeight = foundEl.clientHeight;
const targetOffsetTop = document.querySelector(`.home__content_comp div:nth-child(${index+1})`).offsetTop-40
// 获取当前 offsetTop
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义一次跳 50 个像素,数字越大跳得越快,但是会有掉帧得感觉,步子迈大了会扯到蛋
const STEP = 50
// 判断是往下滑还是往上滑
if (scrollTop > targetOffsetTop) {
// 往上滑
smoothUp()
} else {
// 往下滑
smoothDown()
}
// 定义往下滑函数
function smoothDown() {
// 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
if (scrollTop < targetOffsetTop) {
// 如果和目标相差距离大于等于 STEP 就跳 STEP
// 否则直接跳到目标点,目标是为了防止跳过了。
if (targetOffsetTop - scrollTop >= STEP) {
scrollTop += STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
// 关于 requestAnimationFrame 可以自己查一下,在这种场景下,相比 setInterval 性价比更高
requestAnimationFrame(smoothDown)
}
}
// 定义往上滑函数
function smoothUp() {
if (scrollTop > targetOffsetTop) {
if (scrollTop - targetOffsetTop >= STEP) {
scrollTop -= STEP
} else {
scrollTop = targetOffsetTop
}
document.body.scrollTop = scrollTop
document.documentElement.scrollTop = scrollTop
requestAnimationFrame(smoothUp)
}
}
}
css
<style scoped lang="scss">
.searchBar {
width: 100%;
.isFixed {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 999;
}
ul {
height: 40px;
line-height: 40px;
display: flex;
margin:0;
padding: 0;
li {
font-size: 0.8rem;
flex: 1;
display: flex;
justify-items: center;
justify-content: center;
align-items: center;
align-content: center;
position: relative;
background-color: #fff;
&.active {
color: #847ec3;
background-color: #e2e2e2;
&:after {
content: " ";
position: absolute;
height: 1px;
width: 30px;
bottom: 6px;
left:calc(50% - 15px);
border-top: 2px #847ec3 solid;
}
}
}
}
}
</style>
二、再建个HomeContent.vue
这个页面就比较简单了
<template>
<div>
<naigate-tool></naigate-tool>
<!-- 内容区域 -->
<div class="home__content_comp">
<div>
This is first page.
</div>
<div>
This is second page.
</div>
<div>
This is third page.
</div>
<div>
This is fourth page.
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import NaigateTool from './NavigateTool';
export default {
name:'HomeContent',
components:{
NaigateTool
}
}
</script>
<style scoped>
/* 内容区的样式 */
.home__content_comp {
background-color: white;
width: 100%;
}
.home__content_comp div {
width: 100%;
height: 600px;
font-size: 26px;
background-color: #7ec384;
}
.home__content_comp div:nth-child(2n) {
background-color: #847ec3;
}
</style>
参考案例:
vue的滚动scroll事件 实现某元素吸顶或者固定位置显示
vue横向导航条滚动到顶部固定同时瞄点对应内容(copy即用)的更多相关文章
- RN 使用react-navigation写可以滚动的横向导航条
在react-native中写横向导航条,首选肯定是react-navigation的createMaterialTopTabNavigator,附上官方文档链接.https://reactnavig ...
- css横向导航条
css横向导航条有两种方法 1. ul li a li{float:left} #navlist li, #navlist a{height:44px;display:block;} a{width: ...
- iOS:导航条滚动透明度随着tableView的滚动而变化
来源:HelloYeah 链接:http://www.jianshu.com/p/b8b70afeda81 下面这个界面有没有觉得很眼熟.打开你手里的App仔细观察,你会发现很多都有实现这个功能.比如 ...
- 元素随屏幕滚动到顶部固定js效果
网站中常见这种效果,某个广告或详情页切换tab,当屏幕向下移动时,该元素会停留在浏览器最顶部,下面ecshop模板中心教您实现js代码: 案例图: 1.首先在页面上找到该元素 加上 id =&quo ...
- 使用css实现移动端导航条滚动
<div class="tab"> <div class="table-item"> <span class="tab- ...
- Nuxt/Vue自定义导航栏Topbar+标签栏Tabbar组件
基于Vue.js实现自定义Topbar+Tabbar组件|仿咸鱼底部凸起导航 最近一直在倒腾Nuxt项目,由于Nuxt.js是基于Vue.js的服务端渲染框架,只要是会vue,基本能很快上手了. 一般 ...
- Bootstrap每天必学之导航条
http://www.jb51.net/article/75534.htm Bootstrap每天必学之导航条,本文向大家讲解了多种多样的导航条,以及导航条中元素的实现方法,感兴趣的小伙伴们可以参考一 ...
- bootstrap 组件之"导航条"
一个典型的导航条基本代码如下: <nav class="navbar navbar-default"> <div class="container&qu ...
- bootstrap导航条相关知识
在导航条(navbar)中有一个背景色.而且导航条可以是纯链接(类似导航),也可以是表单,还有就是表单和导航一起结合等多种形式. 为导航条添加标题.二级菜单及状态 <div class=&quo ...
- Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
本博主在一次个人移动端项目中,遇到这么一个需求:希望自己的项目中,头部导航条的效果可以像今日头条那样,横向滚动! 对于这样的效果,在各大移动端项目中几乎是随处可见,为什么呢? 我们都知道,对于移动端也 ...
随机推荐
- Android 音视频 - EGL 源码解析以及 C++ 实现
OpenGL 是一个跨平台的 API,而不同的操作系统(Windows,Android,IOS)各有自己的屏幕渲染实现.所以 OpenGL 定义了一个中间接口层 EGL(Embedded Graphi ...
- 获得New Bing资格后,在Ubuntu环境下使用New Bing
技术背景 如今基于GPT-4的New Bing,结合搜索引擎的功能,可以说已经达到了非常高的智力水平.虽说ChatGPT的出现打击了很多的行业,但是对我们来说也未必不是一种机遇.合理的使用ChatGP ...
- 关于lambda的由来
总结lambda表达式的本质就是匿名方法,根据委托推断类型 class Program { static void Main(string[] args) { //泛型委托 最后一个是返回值 Acti ...
- Nacos 实现 AP+CP原理[Raft 算法 NO]
来源于网络 一.什么是 Raft算法 Raft 适用于一个管理日志一致性的协议,相比于 Paxos 协议 Raft 更易于理解和去实现它.为了提高理解性,Raft 将一致性算法分为了几个部分,包括领导 ...
- EasyRelation发布,简单强大的数据关联框架
当开发人员需要进行关联查询时,往往需要编写大量的冗余代码来处理数据之间的关系.这不仅浪费时间和精力,还会影响项目的可维护性和可扩展性. EasyRelation 是一个简单.高效的自动关联数据框架,可 ...
- vue3 封装el-table时,构造$children(类式写法)
由于业务需求(组件封装),需要在获取el-table下面的el-table-column实例 在 vue2.x 当中直接使用this.$children就可以获取到该实例 但是 vue3.x 弃用了$ ...
- 补五月四号java基础知识
1.在JDK5中新增了自动包装和自动解包功能:当编译器发现程序再应该使用包装类对象的地方却使用基本数据类型的数据时,编译器将自动把该数据包装为该基本数据对应的包装类的对象,这个过程成为自动包装.如类型 ...
- internal java compiler error
1.导入Maven项目运行报错: 解决方法:找到File->Settings 修改配置 再次运行就可以了.
- LeeCode 栈与队列问题(二)
LeeCode 239: 滑动窗口最大值 题目描述 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右 ...
- LeeCode链表问题(一)
本文中所使用的链表定义如下所示: # Definition for singly-linked list. class ListNode: def __init__(self, val=0, next ...

