js实现点击选项置顶动画效果

yizhihongxing

让我详细讲解一下如何实现JS点击选项置顶动画效果的攻略。

1. 思路分析

首先,我们需要明确思路,一般来说实现点击选项置顶的效果,我们需要先获取到页面上所有需要滚动到的位置,然后给所有的选项注册点击事件,当点击某一个选项时,获取需要滚动到的位置,然后使用JS实现滚动动画效果即可。

2. 获取元素的位置信息

在实现滚动动画效果之前,我们首先需要获取每个元素的位置信息,即每个选项需要滚动到的位置。这里,我们可以使用JS的offsetTop属性来获取每个元素的相对于文档顶部的位置,具体代码如下所示:

const navLinks = document.querySelectorAll('.navbar-nav a');
const sections = document.querySelectorAll('section');
const sectionOffsets = [];
for (let i = 0; i < sections.length; i++) {
  sectionOffsets[i] = sections[i].offsetTop;
}

上述代码中,我们首先使用querySelectorAll方法获取到所有的导航链接和页面所有的内容区域,然后使用一个数组sectionOffsets来保存每个内容区域相对于文档顶部的位置。在这里,我们使用了一个循环遍历所有内容区域,并通过offsetTop属性获取每个元素相对于文档顶部的位置信息。

3. 注册点击事件

接下来,我们需要为所有的导航链接注册点击事件,当用户点击某个链接时,页面会滚动到对应的内容区域。这里,我们可以通过addEventListener方法来为每个链接添加click事件,然后在事件处理函数中实现页面滚动的动画效果。具体代码如下所示:

for (let i = 0; i < navLinks.length; i++) {
  navLinks[i].addEventListener('click', function(event) {
    event.preventDefault();
    const targetSection = event.target.getAttribute('data-link');
    const targetOffset = sectionOffsets[targetSection];
    scrollToSection(targetOffset);
  })
}

上述代码中,我们使用了一个循环遍历所有的链接,然后为每个链接添加一个click事件监听器,当链接被点击时,我们会通过getAttribute方法获取到目标内容区域的索引,然后再利用之前获取到的位置信息来实现滚动动画。

可以看到,我们在代码中调用了一个scrollToSection函数来实现动画效果,接下来我们就来实现这个函数。

4. 实现滚动动画

最后一步,我们需要实现滚动动画效果,让页面滑动到目标位置。这里,我们可以使用setTimeoutrequestAnimationFrame方法实现一个平滑滚动的过程,具体代码如下所示:

function scrollToSection(offset) {
  const start = window.pageYOffset;
  const distance = offset - start;
  const duration = 300;
  let startTime = null;

  function scroll(timestamp) {
    if (!startTime) {
      startTime = timestamp;
    }
    const progress = timestamp - startTime;
    const ease = easing(progress / duration);
    window.scrollTo(0, start + distance * ease);
    if (progress < duration) {
      requestAnimationFrame(scroll);
    }
  }

  requestAnimationFrame(scroll);
}

function easing(t) {
  return t * t * t;
}

上述代码中,我们根据目标位置与当前位置的差值计算出滚动的距离,然后使用requestAnimationFrame方法实现一个平滑的动画过程。我们通过scroll函数来实现具体的滚动过程,其中,我们通过window.scrollTo方法来实现页面滚动效果,然后使用递归调用requestAnimationFrame方法完成滚动过程中的帧动画。我们还定义了一个easing函数来控制滚动动画的加速度。

5. 示例说明

为了更好的说明实现过程,这里再提供两个示例:

示例1:

在页面中有三个内容区域分别是Introduction、Features和Contact Us,对应的导航链接分别是Introduction、Features和Contact Us。当用户点击Introduction链接时,页面滚动到Introduction内容区域;当用户点击Features链接时,页面滚动到Features内容区域;当用户点击Contact Us链接时,页面滚动到Contact Us内容区域。

HTML代码:

<nav class="navbar">
  <ul class="navbar-nav">
    <li class="nav-item"><a href="#" data-link="0">Introduction</a></li>
    <li class="nav-item"><a href="#" data-link="1">Features</a></li>
    <li class="nav-item"><a href="#" data-link="2">Contact Us</a></li>
  </ul>
</nav>

<section id="section-1">
  <h1>Introduction</h1>
</section>

<section id="section-2">
  <h1>Features</h1>
</section>

<section id="section-3">
  <h1>Contact Us</h1>
</section>

JS代码:

const navLinks = document.querySelectorAll('.navbar-nav a');
const sections = document.querySelectorAll('section');
const sectionOffsets = [];

for (let i = 0; i < sections.length; i++) {
  sectionOffsets[i] = sections[i].offsetTop;
}

for (let i = 0; i < navLinks.length; i++) {
  navLinks[i].addEventListener('click', function(event) {
    event.preventDefault();
    const targetSection = event.target.getAttribute('data-link');
    const targetOffset = sectionOffsets[targetSection];
    scrollToSection(targetOffset);
  })
}

function scrollToSection(offset) {
  const start = window.pageYOffset;
  const distance = offset - start;
  const duration = 300;
  let startTime = null;

  function scroll(timestamp) {
    if (!startTime) {
      startTime = timestamp;
    }
    const progress = timestamp - startTime;
    const ease = easing(progress / duration);
    window.scrollTo(0, start + distance * ease);
    if (progress < duration) {
      requestAnimationFrame(scroll);
    }
  }

  requestAnimationFrame(scroll);
}

function easing(t) {
  return t * t * t;
}

示例2:

在一个页面中有10个内容区域和导航条,当用户距离页面顶部超过300px时,导航条固定在页面顶部,用户在滑动页面时,导航随之滑动,当用户点击导航链接时,页面滚动到相应的内容区域。

HTML代码:

<nav class="navbar">
  <ul class="navbar-nav">
    <li class="nav-item"><a href="#" data-link="0">Section 1</a></li>
    <li class="nav-item"><a href="#" data-link="1">Section 2</a></li>
    <li class="nav-item"><a href="#" data-link="2">Section 3</a></li>
    <li class="nav-item"><a href="#" data-link="3">Section 4</a></li>
    <li class="nav-item"><a href="#" data-link="4">Section 5</a></li>
    <li class="nav-item"><a href="#" data-link="5">Section 6</a></li>
    <li class="nav-item"><a href="#" data-link="6">Section 7</a></li>
    <li class="nav-item"><a href="#" data-link="7">Section 8</a></li>
    <li class="nav-item"><a href="#" data-link="8">Section 9</a></li>
    <li class="nav-item"><a href="#" data-link="9">Section 10</a></li>
  </ul>
</nav>

<div class="spacer"></div>

<section id="section-1">
  <h1>Section 1</h1>
</section>

<section id="section-2">
  <h1>Section 2</h1>
</section>

<section id="section-3">
  <h1>Section 3</h1>
</section>

<section id="section-4">
  <h1>Section 4</h1>
</section>

<section id="section-5">
  <h1>Section 5</h1>
</section>

<section id="section-6">
  <h1>Section 6</h1>
</section>

<section id="section-7">
  <h1>Section 7</h1>
</section>

<section id="section-8">
  <h1>Section 8</h1>
</section>

<section id="section-9">
  <h1>Section 9</h1>
</section>

<section id="section-10">
  <h1>Section 10</h1>
</section>

CSS代码:

.navbar {
  position: relative;
  z-index: 999;
  background-color: #fff;
}

.spacer {
  height: 80px;
}

.sticky-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

.current {
  color: #f00;
}

JS代码:

const navLinks = document.querySelectorAll('.navbar-nav a');
const sections = document.querySelectorAll('section');
const sectionOffsets = [];
const navbar = document.querySelector('.navbar');
const spacer = document.querySelector('.spacer');
let isSticky = false;

for (let i = 0; i < sections.length; i++) {
  sectionOffsets[i] = sections[i].offsetTop;
}

window.addEventListener('scroll', function(event) {
  const scrollTop = window.pageYOffset;
  if (scrollTop > 300 && !isSticky) {
    navbar.classList.add('sticky-nav');
    spacer.style.paddingTop = navbar.offsetHeight + 'px';
    isSticky = true;
  } else if (scrollTop <= 300 && isSticky) {
    navbar.classList.remove('sticky-nav');
    spacer.style.paddingTop = '0';
    isSticky = false;
  }

  const currentSection = getCurrentSection(scrollTop, sectionOffsets);
  setActiveLink(currentSection);
})

function getCurrentSection(scrollTop, sectionOffsets) {
  for (let i = sectionOffsets.length - 1; i >= 0; i--) {
    if (scrollTop >= sectionOffsets[i] - 100) {
      return i;
    }
  }
  return 0;
}

function setActiveLink(index) {
  for (let i = 0; i < navLinks.length; i++) {
    navLinks[i].classList.remove('current');
  }
  navLinks[index].classList.add('current');
}

for (let i = 0; i < navLinks.length; i++) {
  navLinks[i].addEventListener('click', function(event) {
    event.preventDefault();
    const targetSection = event.target.getAttribute('data-link');
    const targetOffset = sectionOffsets[targetSection];
    scrollToSection(targetOffset);
  })
}

function scrollToSection(offset) {
  const start = window.pageYOffset;
  const distance = offset - start;
  const duration = 300;
  let startTime = null;

  function scroll(timestamp) {
    if (!startTime) {
      startTime = timestamp;
    }
    const progress = timestamp - startTime;
    const ease = easing(progress / duration);
    window.scrollTo(0, start + distance * ease);
    if (progress < duration) {
      requestAnimationFrame(scroll);
    }
  }

  requestAnimationFrame(scroll);
}

function easing(t) {
  return t * t * t;
}

上述代码中,我们实现了一个页面滚动时导航条固定在页面顶部的效果,并且在用户点击导航链接时,页面会滚动到相应的内容区域。在代码中,我们使用了getBoundingClientRect方法来获取元素相对于视口的位置信息,并通过监听scroll事件来实时更新导航条的位置。此外,我们还通过getCurrentSection函数来实时判断当前应该显示哪一个内容区域,并通过setActiveLink函数来设置当前选择的导航链接的样式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js实现点击选项置顶动画效果 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 现代 javscript 编程 资料第2/6页

    我们来详细解析“现代JavaScript编程资料第2/6页”的完整攻略吧。 背景介绍 这份资料是介绍现代 JavaScript 编程的,旨在帮助初学者快速入门并熟练掌握现代 JavaScript 的相关技术和特性。 攻略步骤 以下是学习该资料的详细攻略步骤: 1. 熟悉资料结构 该资料的第2/6页主要介绍了以下内容: ES6 模块化 Promises 迭代器…

    JavaScript 2023年6月10日
    00
  • 显示js对象所有属性和方法的函数

    要显示 JS 对象的所有属性和方法,需要使用以下两种方法之一。 方法一:for…in 循环 使用 for…in 循环可遍历该对象所有可枚举的属性名称,从而显示对象的属性和方法。 function showProperties(obj) { for (var propName in obj) { console.log(propName); } } 该…

    JavaScript 2023年5月27日
    00
  • js统计页面的来访次数实现代码

    要实现 js 统计页面来访次数,需要用到以下步骤: 创建一个用来记录访问次数的变量 首先,我们需要创建一个变量来储存网页的访问次数。这个计数器可以使用本地存储(localStorage)来保存,保证每次刷新页面访问次数不会被重置。 // 初始化访问次数为0 var pageViewCount = 0; // 在本地存储中查找是否有访问次数 if (local…

    JavaScript 2023年6月11日
    00
  • 小程序animate动画实现直播间点赞

    下面是关于小程序animate动画实现直播间点赞的完整攻略: 1. 准备工作 在开始实现动画之前,需要先将点赞的代码逻辑实现,即点击点赞按钮后,更新点赞数量并发送点赞请求。 2. 使用CSS动画实现点赞效果 使用wx.createAnimation创建一个动画对象,并设置一个或多个CSS属性。 “`js const animation = wx.creat…

    JavaScript 2023年6月11日
    00
  • JavaScript中错误正确处理方式小结你用对了吗

    让我来详细讲解一下 “JavaScript中错误正确处理方式小结你用对了吗” 这个话题。 标题 JavaScript中错误正确处理方式小结你用对了吗 简介 在JavaScript中,错误处理一直是一个非常重要的主题。如果没有适当的错误处理,代码可能会运行失败或者执行不完整。因此,正确处理错误是每个JavaScript开发人员的必修课程。 常见错误类型 在Ja…

    JavaScript 2023年5月28日
    00
  • 表单提交(插入效果)javascript

    下面我将给你详细讲解“表单提交(插入效果)JavaScript”的完整攻略。 概述 表单提交指的是将用户在网页上填写的表单数据提交到后端服务器进行处理。通常情况下,我们需要通过JavaScript来实现这个功能。在实现表单提交时,还可以添加插入效果,以提高用户体验。 实现步骤 下面是实现表单提交(插入效果)的步骤: 获取表单对象,并设置表单提交事件,当表单提…

    JavaScript 2023年6月11日
    00
  • Electron vue的使用教程图文详解

    Electron Vue的使用教程图文详解 Electron Vue是一款基于Electron和Vue的框架,可以用于快速构建桌面应用。本文将详细讲解如何使用Electron Vue构建桌面应用程序。 前置条件 在开始使用Electron Vue之前,需要具备以下技能和工具: 基本的HTML、CSS和JavaScript技能 Vue.js的基础知识 Node…

    JavaScript 2023年6月11日
    00
  • JavaScript中reduce()的5个基本用法示例

    当我们需要把一个数组变成一个单独的数值,或者我们需要使用一个数据结构去处理一个序列的值的时候,JavaScript中的reduce()方法就非常有用。本篇文章将详细讲解JavaScript中reduce()方法的5个基本用法示例,并提供两个具体的代码示例。 reduce()方法的语法 首先,我们需要了解下reduce()方法的语法: arr.reduce(c…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部