【CSS笔记】双向绑定导航栏(页面内位置跳转)

0 简介

场景简介:页面内容分块纵向排布,右侧有导航,导航栏内高亮内容与页面位置双向绑定

简单构建纵向页面与导航栏:

html 复制代码
<template>
  <div class="main-container">
    <div class="info-wrap">
      <div class="info-wrap-title">内容板块1</div>
      <div class="info-wrap-content">
        ...
      </div>
    </div>
    
    <div class="info-wrap">
      <div class="info-wrap-title">内容板块2</div>
      <div class="info-wrap-content">
        ...
      </div>
    </div>
    
    ...
    
    <div class="info-wrap">
      <div class="info-wrap-title">内容板块10</div>
      <div class="info-wrap-content">
        ...
      </div>
    </div>
    
    <div class="vertical-navbar">
      <div
        v-for="(item, key) in 10"
        :key="key"
        class="vertical-navbar-item"
      >
        内容板块{{ key + 1 }}
      </div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.main-container {
  position: relative;
}

// 导航栏固定在页面右方
.vertical-navbar {
  position: fixed;
  top: 100px;
  right: 100px;
  
  // 内容竖向排布
  display: flex;
  flex-direction: column;
}
</style>

1 导航栏根据根据页面滑动位置变化

需要使用 css 新功能 timeline-scope

1.1 设置标记索引及标记高亮条件

1.1.1 设置标记索引

在内容板块 .info-wrap 中设置标记索引

css 复制代码
.info-wrap {
  ...
  // 设置标记索引
  view-timeline-name: var(--s);
}

1.1.2 设置高亮条件

在内容板块 .info-wrap 上设置高亮条件

css 复制代码
.info-wrap {
  ...
  // 设置高亮条件
  view-timeline-inset: 0 100%; // 标记进入区域范围后高亮
}

view-timeline-inset 设置的两个属性之和为 100% 最好,可以自行调试看效果。

1.2 设置标记并增加高亮样式

1.2.1 设置标记

在内容板块标题 .info-wrap-title 上设置标记

html 复制代码
<div class="info-wrap" style="--s: --t1;">
  <div class="info-wrap-title">内容板块1</div>
  ...
</div>

<div class="info-wrap" style="--s: --t2;">
  <div class="info-wrap-title">内容板块2</div>
  ...
</div>

...

在导航栏内容 .vertical-navbar-item 上绑定同样的标记

html 复制代码
<div class="vertical-navbar">
  <div class="vertical-navbar-item" style="--s: --t1;">内容板块1</div>
  <div class="vertical-navbar-item" style="--s: --t2;">内容板块2</div>
  ...
</div>

1.2.2 配置高亮样式

在导航栏内容 .vertical-navbar-item 上配置高亮样式

css 复制代码
.vertical-navbar-item {
  ...
  // 设置高亮样式
  border-left: 2px solid #D9DEE9; // 默认样式
  animation: active; // 高亮动画
  animation-timeline: var(--s); // 高亮动画绑定索引
  // 高亮动画
  @keyframes active {
    0%, 100% {
      border-left: 2px solid #D9DEE9; // 默认样式
      border-left: 2px solid #006CFF; // 高亮样式
    }
  }  
}

1.3 注册标记

在纵向页面容器 .main-container 中注册标记

css 复制代码
.main-container {
  ...
  // 之前设置了多少个标记,全都注册在这
  timeline-scope: --t1, --t2, --t3, --t4, --t5, --t6, --t7, --t8, --t9, --t10;
}

完成以上设置,便可以实现导航栏根据根据页面位置变化的效果。

2 页面位置随导航栏按钮点击事件变化

2.1 使用 id<a> 链接跳转

2.1.1 设置 id

在内容板块标题 .info-wrap-title 上设置 id

html 复制代码
<div class="info-wrap" style="--s: --t1;">
  <div id="t1" class="info-wrap-title">内容板块1</div>
  ...
</div>

<div class="info-wrap" style="--s: --t2;">
  <div id="t2" class="info-wrap-title">内容板块2</div>
  ...
</div>

...

2.1.2 设置 <a> 跳转地址

将导航栏内容变为 <a>,并设置 href

html 复制代码
<div class="vertical-navbar">
  <a href="#t1" class="vertical-navbar-item" style="--s: --t1;">内容板块1</a>
  <a href="#t2" class="vertical-navbar-item" style="--s: --t2;">内容板块2</a>
  ...
</div>

2.1.3 页面丝滑滚动

提升视觉效果,设置页面丝滑滚动

css 复制代码
.main-container {
  ...
  // 设置滚动丝滑
  scroll-behavior: smooth;
}

如此,导航栏点击后页面随之滚动,便实现了双向绑定。 这个方法会导致页面地址随之变化,页面刷新和回退都会受到影响。

2.2 借助 js 实现跳转

2.2.1 js 跳转方法

js 复制代码
changeHash(id) {
  window.document.querySelector(id).scrollIntoView(true)
}

2.2.2 绑定方法

在导航栏内容上绑定方法

html 复制代码
<div class="vertical-navbar">
  <div class="vertical-navbar-item" style="--s: --t1;" @click="changeHash('#t1')">内容板块1</a>
  <div class="vertical-navbar-item" style="--s: --t1;" @click="changeHash('#t2')">内容板块1</a>
  ...
</div>

如此,便实现了页面内导航功能,且地址不会变化。

笔记主要为自用,欢迎友好交流!

内容参考站内文:juejin.cn/post/739634...

相关推荐
祈澈菇凉2 小时前
Webpack的基本功能有哪些
前端·javascript·vue.js
小纯洁w2 小时前
Webpack 的 require.context 和 Vite 的 import.meta.glob 的详细介绍和使用
前端·webpack·node.js
想睡好3 小时前
css文本属性
前端·css
qianmoQ3 小时前
第三章:组件开发实战 - 第五节 - Tailwind CSS 响应式导航栏实现
前端·css
zhoupenghui1683 小时前
golang时间相关函数总结
服务器·前端·golang·time
White graces3 小时前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
庸俗今天不摸鱼3 小时前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
bubusa~>_<3 小时前
解决npm install 出现error,比如:ERR_SSL_CIPHER_OPERATION_FAILED
前端·npm·node.js
流烟默4 小时前
vue和微信小程序处理markdown格式数据
前端·vue.js·微信小程序
梨落秋溪、4 小时前
输入框元素覆盖冲突
java·服务器·前端