首页 > 解决方案 > 在 Chrome 中的多个元素上使用平滑函数的 scrollIntoView()

问题描述

element.scrollIntoView将行为设置为smooth在 Chrome 中无法正常工作。当它仅用于调用堆栈中的一个元素时,它可以正常工作。但如果它用于多个元素,只有最后一个元素会真正滚动。

这在 Firefox 中运行良好。Chrome中是否有解决方法?

const $ = (s) => document.querySelector(s)
const $$ = (s) => document.querySelectorAll(s)

const container = $(".container")

for (let i = 0; i < 2; i++) {
  document.body.appendChild(container.cloneNode(true))
}

function scrollIntoView(behavior) {
  for (const element of $$(".reveal")) {
    element.scrollIntoView({
      behavior,
      block: "end"
    })
  }
}

$(".instant").addEventListener("click", () => scrollIntoView("instant"))

$(".smooth").addEventListener("click", () => scrollIntoView("smooth"))

$(".reset").addEventListener("click", () => {
  for (const element of $$(".container")) {
    element.scrollTo(0, 0)
  }
})
.container {
  max-height: calc(33vh - 12px);
  overflow-y: auto;
}

.reveal {
  color: red;
}
<button class="instant">
Instant
</button>
<button class="smooth">
Smooth
</button>
<button class="reset">
Reset
</button>
<div class="container">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus elementum quam. Donec quis est volutpat, dapibus nisl at, consequat turpis. Quisque convallis nunc faucibus eros egestas, in faucibus neque fringilla. Duis aliquam, metus tempor dignissim
  vestibulum, nulla elit lacinia lacus, vitae pulvinar augue diam et turpis. Aenean a velit sed elit dictum fringilla ut eu augue. Vestibulum hendrerit dolor mauris. Proin quis lacus a turpis posuere maximus. Sed lacus mauris, feugiat a iaculis porta,
  lacinia vel eros. Integer tempor id tortor vitae fermentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam lobortis efficitur massa, eu elementum nulla eleifend ut. Quisque non erat iaculis, ornare erat non, interdum sapien. Suspendisse
  sit amet interdum nisl, eu maximus libero. Fusce nisi nulla, iaculis eu est a, mattis tincidunt sem. Pellentesque non orci dapibus, dignissim ipsum a, finibus metus. Quisque placerat porta neque, eget finibus lectus tempus sed. Cras non gravida urna.
  Morbi pretium mauris nec erat consectetur, vitae convallis lacus consectetur. Nam venenatis diam magna, sed venenatis nisl placerat viverra. Integer et mi pellentesque risus consectetur ultrices. Phasellus iaculis risus elementum, vulputate est sed,
  consectetur diam. Phasellus lobortis felis purus, sit amet mattis elit pharetra ac. Nulla at viverra leo. Maecenas a condimentum magna. Maecenas porta tellus sit amet elit fermentum tincidunt. Donec ultricies blandit enim id mollis. Sed rutrum risus
  sit amet posuere varius. Suspendisse suscipit maximus ligula eget egestas. Nullam lorem neque, viverra in sollicitudin ac, cursus nec purus. Aliquam placerat, arcu sit amet tincidunt consequat, ex est lacinia tellus, ac mattis nisl sapien at enim. Cras
  lacinia libero eu eleifend sodales. Praesent a erat convallis, venenatis dui ut, semper sem. Vivamus tincidunt tempor neque, at congue lacus tincidunt et. Praesent consectetur, massa tristique laoreet sollicitudin, erat diam mattis nibh, nec consequat
  mauris odio ut est. Integer pharetra arcu at finibus congue. Proin pellentesque fringilla blandit. Suspendisse egestas interdum nisl. Nulla facilisi. Quisque dapibus odio risus. Donec non orci dapibus risus pellentesque cursus vestibulum vel arcu. Proin
  volutpat tellus sed elit auctor, sit amet tincidunt ante cursus. Donec faucibus sit amet libero sit amet lobortis. Pellentesque posuere nisl vitae pharetra vestibulum. Mauris et lobortis libero, vel facilisis metus. Duis eu venenatis dui. Fusce gravida
  nibh odio, quis ullamcorper nibh rutrum sed. In dapibus, nulla non auctor egestas, nisi augue venenatis quam, et finibus lorem dui non turpis. Nullam arcu diam, mattis at erat ac, viverra lobortis felis. In in nisi magna. Ut ut ultrices velit, quis
  vehicula libero. Proin dictum metus vel ante lobortis, in placerat magna ornare. Etiam vulputate metus felis, sed fringilla magna convallis vitae. Curabitur non pulvinar ante, eget molestie nibh. Quisque facilisis, diam sed dapibus blandit, ex urna
  vulputate est, non auctor risus dui nec augue. Donec pretium laoreet est, tempor faucibus tortor laoreet ac.
  <span class="reveal">Revealed!</span>
</div>

标签: javascripthtmlcssgoogle-chrome

解决方案


根据 drafts.c​​sswg.org 上的这个草稿,不能使用平滑功能同时滚动多个元素;

当用户代理要执行滚动框的滚动,到给定的位置位置、关联的元素元素和可选的滚动行为行为(如果省略,则为“自动”),必须运行以下步骤:

  1. 中止任何正在进行的平滑滚动框。
  2. 如果用户代理尊重滚动行为属性并且以下之一为真:
    • 行为是“自动”并且元素不为空,并且其滚动行为属性的计算值是平滑的
    • 行为平稳

...然后执行平滑滚动框到位置。否则,执行框的即时滚动到位置。

您的选择是:

  • 使用原生平滑功能一一滚动元素。
  • 使用不同的 API 或库为元素设置动画。
  • 在功能上设计不同的东西,所以它们不需要同时滚动。

推荐阅读