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组件)实现类似头条效果的横向滚动导航条
本博主在一次个人移动端项目中,遇到这么一个需求:希望自己的项目中,头部导航条的效果可以像今日头条那样,横向滚动! 对于这样的效果,在各大移动端项目中几乎是随处可见,为什么呢? 我们都知道,对于移动端也 ...
随机推荐
- 做bad apple第一步:超级好用的you-get下载各大网站音频!!!!
1 安装在cmd中输入pip3 install you-get 就行了 2 简单用法下载视频: 超级暴力,直接 you-get + "网站" 就没了,会下载到当前路径.我想下载到哪 ...
- 声网传输层协议 AUT 的总结与展望丨Dev for Dev 专栏
本文为「Dev for Dev 专栏」系列内容,作者为声网大后端传输协议负责人 夏天. 针对实时互动应用对网络传输带来的新需求和新挑战,声网通过将实时互动中的应用层业务需求与传输策略的分层和解耦,于 ...
- Vue+ElementUI动态显示el-table某列(值和颜色)的方法
方法一:结合 template scope组件和 v-if 语法判断 例1:值 <el-table-column prop="status" label="车辆状态 ...
- .Net 6.0定义全局当前身份缓存对象
背景: 当前身份缓存对象顾名思义就是:当前登录的用户身份对象,那它解决了什么问题呢?其实在我们日常开发过程中经常能用的到几乎是必备的,就比如我给某个表插入数据时需要创建人或者一些权限的访问,都得用到当 ...
- selenium验证码处理-获取验证码图片二进流数据转成原图保存
1.因为视频的作者给的代码不完整,只有核心部分的代码. 2.视频作者示例使用的第三方破解12306的脚本网页(失效了) 所以本人无法复现,此次截取部分代码作为理解核心意思(思想方法最重要) 1.面向对 ...
- Low-Code,一定“low”吗?
作者:京东保险 吴凯 前言 低代码是一组数字技术工具平台,基于图形化拖拽.参数化配置等更为高效的方式,实现快速构建.数据编排.连接生态.中台服务.通过少量代码或不用代码实现数字化转型中的场景应用创新. ...
- R语言网络数据爬虫之三个问题
现在大家对爬虫的兴趣不断高涨,R和PYTHON是两个非常有力的爬虫工具.Python倾向于做大型爬虫,与R相比,语法相对复杂,因此Python爬虫的学习曲线会相对陡峭.对于那些时间宝贵,又想从网上获取 ...
- cephadm 安装部署 ceph 集群
介绍 手册: https://access.redhat.com/documentation/zh-cn/red_hat_ceph_storage/5/html/architecture_guide/ ...
- [数据库]Ubuntu Linux/Kylin: 安装MySQL
1 文由 由于安装环境较为特殊,实在折煞人也.而此环境的网络博客/教程偏少,觉得有必要记录一下. 2 环境 安装主机不支持联网 即 不支持APT/APT-GET等傻瓜式的在线安装方式. 硬件架构: A ...
- 四月十三号java基础知识
1.双层for循环外层要写,但是内层一定要写,不然容易报错2.Exception in thread "main" java.lang.ArrayIndexOutOfBoundsE ...

