You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular 5中实现无jQuery的平滑滚动效果

替代jQuery平滑滚动的原生JS与Angular 5实现方案

我来帮你搞定这个问题!你现在需要把依赖jQuery的平滑滚动逻辑改成无依赖的实现,不管是原生JS还是符合Angular 5风格的写法都可以,下面给你两种实用方案:


方案一:原生JavaScript实现(无任何依赖)

这个方案完全脱离jQuery,用requestAnimationFrame实现流畅的动画,还能模拟jQuery默认的缓动效果,精确控制800ms的滚动时长:

function smoothScroll() {
  // 获取父容器和目标元素
  const parentElement = document.querySelector('.parent-class');
  const targetElement = document.getElementById('scrllhere');
  
  // 避免元素不存在导致报错
  if (!parentElement || !targetElement) return;

  // 计算目标滚动位置(和你的jQuery逻辑一致:目标元素顶部+10)
  const targetPosition = targetElement.offsetTop + 10;
  const startPosition = parentElement.scrollTop;
  const scrollDistance = targetPosition - startPosition;
  const duration = 800; // 滚动时长,和原代码一致
  let animationStart = null;

  // 动画帧函数
  function animateScroll(currentTime) {
    if (animationStart === null) animationStart = currentTime;
    const timeElapsed = currentTime - animationStart;
    // 计算进度,确保不超过100%
    const progress = Math.min(timeElapsed / duration, 1);
    
    // 加入缓动函数,模拟jQuery animate的默认ease-in-out效果
    const easeProgress = progress < 0.5 
      ? 2 * progress * progress 
      : 1 - Math.pow(-2 * progress + 2, 2) / 2;
    
    // 更新滚动位置
    parentElement.scrollTop = startPosition + (scrollDistance * easeProgress);
    
    // 未完成则继续调用下一帧
    if (timeElapsed < duration) {
      requestAnimationFrame(animateScroll);
    }
  }

  // 启动动画
  requestAnimationFrame(animateScroll);
}

如果不需要自定义缓动,现代浏览器还支持更简洁的原生scrollTo方法(注意:部分浏览器不支持自定义时长,behavior: 'smooth'会使用浏览器默认时长):

function smoothScroll() {
  const parentElement = document.querySelector('.parent-class');
  const targetElement = document.getElementById('scrllhere');
  
  if (!parentElement || !targetElement) return;

  const targetPosition = targetElement.offsetTop + 10;
  parentElement.scrollTo({
    top: targetPosition,
    behavior: 'smooth'
  });
}

方案二:Angular 5风格实现

Angular的动画模块主要针对组件状态变化,但我们可以结合ViewChild获取DOM元素引用,保持Angular的组件化规范,同时用原生动画逻辑实现:

第一步:模板中添加引用变量

<!-- 给父容器和目标元素添加模板引用 -->
<div #parentContainer class="parent-class">
  <!-- 页面内容 -->
  <div #scrollTarget id="scrllhere">滚动目标位置</div>
</div>

第二步:组件类中实现滚动逻辑

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponent {
  // 通过ViewChild获取DOM元素引用
  @ViewChild('parentContainer') parentContainer: ElementRef;
  @ViewChild('scrollTarget') scrollTarget: ElementRef;

  smoothScroll() {
    const parentEl = this.parentContainer.nativeElement;
    const targetEl = this.scrollTarget.nativeElement;
    
    if (!parentEl || !targetEl) return;

    const targetPosition = targetEl.offsetTop + 10;
    const startPosition = parentEl.scrollTop;
    const scrollDistance = targetPosition - startPosition;
    const duration = 800;
    let animationStart = null;

    const animateScroll = (currentTime: number) => {
      if (animationStart === null) animationStart = currentTime;
      const timeElapsed = currentTime - animationStart;
      const progress = Math.min(timeElapsed / duration, 1);
      
      // 缓动函数
      const easeProgress = progress < 0.5 
        ? 2 * progress * progress 
        : 1 - Math.pow(-2 * progress + 2, 2) / 2;
      
      parentEl.scrollTop = startPosition + (scrollDistance * easeProgress);
      
      if (timeElapsed < duration) {
        requestAnimationFrame(animateScroll);
      }
    };

    requestAnimationFrame(animateScroll);
  }
}

这个方案避免了直接操作DOM,符合Angular的最佳实践,同时实现了和原jQuery代码完全一致的滚动效果。

内容的提问来源于stack exchange,提问作者Vicky Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:36:47