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组件)实现类似头条效果的横向滚动导航条
本博主在一次个人移动端项目中,遇到这么一个需求:希望自己的项目中,头部导航条的效果可以像今日头条那样,横向滚动! 对于这样的效果,在各大移动端项目中几乎是随处可见,为什么呢? 我们都知道,对于移动端也 ...
随机推荐
- 在CentOS中搭建NFS
概述 NFS是一款经典的网络文件系统,在Linux上我们可以通过创建一个NFS服务在不同的服务器之间共享磁盘文件,而不用在多个服务器之间进行不断的拷贝复制,麻烦且浪费存储空间.在k8s中我们也可以使用 ...
- 中兴AX5400Pro+ BUG
中兴AX5400Pro+路由器管理页面已知两个功能出现BUG:1.[应用]栏目下的[父母控制]下的所有设置均不起作用.(更新固件V1.0.0.1B11.8000依然无效)2.[系统]栏目下的[备份配置 ...
- urllib.parse的使用
urllib简介 urllib是pyhton自带的标准库用于网络请求库,无需安装,直接引用 通常用于爬虫开发,API(应用程序编程接口)数据获取和测试 urllib库的4大模块 urllib.requ ...
- Synchronized和Volatile的对比
Synchronized和Volatile是并发中的两大关键字,有相似性和不同点. Synchronized更详细介绍参考https://www.cnblogs.com/spark-cc/p/1706 ...
- 原来还能这样看Java线程的状态及转换
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试.职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜」 大家好,我是呼噜噜,最近一直在梳理Jav ...
- PHP 图片的合并,微信小程序码合并,文字合并
//业务需求:我们需要一个微信小程序码,但是是需要提供给别人扫码的但是只有一个纯粹的小程序码是不好看的,所以需要推广的海报图片.再结合文字 最终效果 准备工作 1.需要海报的底图 2.小程序码的图 ...
- 免费1年服务器,部署个ChatGPT专属网页版
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 白皮袄个免费1年服务器,部署个ChatGPT专属网页版! api.openai.com por ...
- mysql数据类型精讲
1.MySQL中的数据类型 常见数据类型的属性,如下: 2.整数类型2.1 类型介绍整数类型一共有 5 种,包括 TINYINT.SMALLINT.MEDIUMINT.INT(INTEGER)和 BI ...
- 深入理解 python 虚拟机:字节码教程(1)——原来装饰器是这样实现的
深入理解 python 虚拟机:字节码教程(1)--原来装饰器是这样实现的 在本篇文章当中主要给大家介绍在 cpython 当中一些比较常见的字节码,从根本上理解 python 程序的执行.在本文当中 ...
- Mybatis 框架下 SQL 注入攻击的方式
前言 SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少. 新手代码审计者往往对Java Web应用的多个框架组合而心生畏惧,不知如何下手 ...

