【问题标题】:ScrollIntoView doesn't smooth on mobile (Angular)ScrollIntoView 在移动设备上不流畅(Angular)
【发布时间】:2021-02-20 18:31:02
【问题描述】:

我在一个 Angular 项目中创建了一个示例 scrollIntoView。它在网络浏览器上运行良好。但是,当您在移动设备(Chrome 或 Safari)上查看它时,该行为是不稳定的。它会直接跳到没有“平滑”行为的位置。

app.component.html

<button (click)="scroll('one')">One</button>
<button (click)="scroll('two')">Two</button>
<button (click)="scroll('three')">Three</button>
<button (click)="scroll('four')">Four</button>
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>

app.component.ts

export class AppComponent  {
  name = 'Mobile scrollIntoView';

  scroll(id: string) {
    console.log(`scrolling to ${id}`);
    const el = document.getElementById(id);
    el.scrollIntoView({behavior: 'smooth', block: 'start', inline: 'nearest'});
  }
}

您可以在 stackblitz 上查看 - 用手机打开:https://angular-nbpxk7.stackblitz.io

编辑模式:https://stackblitz.com/edit/angular-nbpxk7

我是否遗漏了什么,或者如何在移动设备上存档“流畅”行为?谢谢,

【问题讨论】:

  • 你没有错过任何东西。只是因为 scrollIntoView 不支持 iOS Safari 上的 smooth 行为。 caniuse.com/#feat=scrollintoview
  • 谢谢托安。有没有其他选择?

标签: javascript angular scroll


【解决方案1】:

角度问题似乎不是问题,而是cross-browser compatibility issue。平滑属性几乎不适用于所有移动设备(除了 chrome 和 firefox for android。

here 中,您有一个替代方案,但您需要构建平滑 scrollIntoView 的自定义实现。

为此,我准备了一个自定义函数,您可以根据您的代码在here 中找到完整的工作示例。对于那些想要在 Angular 基础应用程序中使用它的人,您只需将以下函数添加到您的组件中,并通过传递所需的 dom 元素来调用它:

scrollCustomImplementation(element: HTMLElement) {
    let start = null;
    let target = element && element ? element.getBoundingClientRect().top : 0;
    let firstPos = window.pageYOffset || document.documentElement.scrollTop;
    let pos = 0;

    (function () {
      var browser = ['ms', 'moz', 'webkit', 'o'];

      for (var x = 0, length = browser.length; x < length && !window.requestAnimationFrame; x++) {
        window.requestAnimationFrame = window[browser[x] + 'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[browser[x] + 'CancelAnimationFrame'] || window[browser[x] + 'CancelRequestAnimationFrame'];
      }
    })();

    function showAnimation(timestamp) {
      if (!start) {
        start = timestamp || new Date().getTime();
      } //get id of animation


      var elapsed = timestamp - start;
      var progress = elapsed / 600; // animation duration 600ms
      //ease in function from https://github.com/component/ease/blob/master/index.js

      var outQuad = function outQuad(n) {
        return n * (2 - n);
      };

      var easeInPercentage = +outQuad(progress).toFixed(2); // if target is 0 (back to top), the position is: current pos + (current pos * percentage of duration)
      // if target > 0 (not back to top), the positon is current pos + (target pos * percentage of duration)

      pos = target === 0 ? firstPos - firstPos * easeInPercentage : firstPos + target * easeInPercentage;
      window.scrollTo(0, pos);
      console.log(pos, target, firstPos, progress);

      if (target !== 0 && pos >= firstPos + target || target === 0 && pos <= 0) {
        cancelAnimationFrame(start);

        if (element) {
          element.setAttribute("tabindex", -1);
          element.focus();
        }

        pos = 0;
      } else {
        window.requestAnimationFrame(showAnimation);
      }
    }

    window.requestAnimationFrame(showAnimation);
  }

【讨论】:

  • 谢谢里卡多。我在 safari 上试过你的链接,它确实有效!
  • 嗨,Ricardo,我发现向下滚动很流畅。但是,向上滚动很奇怪。能帮忙说一下吗?谢谢,stackblitz.com/edit/angular-nbpxk7
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2018-02-28
  • 2017-07-19
  • 2011-11-03
  • 2020-10-24
相关资源
最近更新 更多