如何使Chrome滚动到包含自动滚动div的部分



我需要一个纯HTML解决方案来滚动到页面上的一个部分。我通常这样做:

html {
scroll-behavior: smooth;
}
#section1 {
background: blue;
height: 500px;
}
#section2 {
background: red;
height: 500px;
}
<a href="#section2">Section 2</a>
<section id="section1"></section>
<section id="section2"></section>

然而,一旦我在页面的某个地方添加了一个自动滚动的div,这就停止了。

function scroll() {
document.getElementById("autoScroll").scrollBy(2, 2);
setTimeout(scroll, 30);
}
scroll();
html {
scroll-behavior: smooth;
}
#section1 {
background: blue;
height: 500px;
}
#section2 {
background: red;
height: 500px;
}
#autoScroll {
height: 200px;
overflow-y: scroll;
}
#content {
height: 500px;
background: green;
}
<a href="#section2">Section 2</a>
<section id="section1"></section>
<section id="section2">
<div id="autoScroll">
<div id="content"></div>
</div>
</section>

这似乎是Chrome独有的问题。至少它在Firefox中运行良好。我是否也需要使用JavascriptscrollIntoView()在Chrome中实现这种效果?或者我缺少一些HTML属性?

以下答案仅对Firefox有效

它仍然在滚动到第2节,但自动滚动元素第2节内部,以覆盖第2节的开头部分的方式。问题出在HTML结构中。

看看:

function scroll() {
document.getElementById("autoScroll").scrollBy(2, 2);
setTimeout(scroll, 30);
}
scroll();
html {
scroll-behavior: smooth;
}
#section1 {
background: blue;
height: 500px;
}
#section2 {
background: red;
height: 500px;
}
#autoScroll {
height: 200px;
overflow-y: scroll;
}
#content {
height: 500px;
background: green;
}
<a href="#section2">Section 2</a>
<section id="section1"></section>
<section id="section2"></section>
<section id="section3">
<div id="autoScroll">
<div id="content"></div>
</div>
</section>

Chromium中的同时卷轴似乎存在问题。

如果将延迟从30ms增加到1000ms,您会注意到,当自动滚动未运行时,定位滚动工作正常,但如果在滚动动画期间自动滚动启动,则会中断。

我找到的解决方法包括在窗口滚动时停止自动滚动,但可能有一些方法可以异步滚动多个元素。

let canScroll = true;
async function scroll() {
if(canScroll) {
document.getElementById("autoScroll").scrollBy(2, 2);
setTimeout(scroll, 30);
}
}
scroll();
document.querySelectorAll('a').forEach(el => el.addEventListener('click', scrollHandler));
async function scrollHandler(e) {
let href = e.target.getAttribute('href');

if(href.startsWith('#')) {
canScroll = false;
document.querySelector(href).scrollIntoView();
setTimeout(() => {
canScroll = true;
scroll();
}, 500);
}
}
html {
scroll-behavior: smooth;
}
#section1 {
background: blue;
height: 500px;
}
#section2 {
background: red;
height: 500px;
}
#autoScroll {
height: 200px;
overflow-y: scroll;
}
#content {
height: 500px;
background: green;
}
<a href="#section2">Section 2</a>
<a href="https://google.com">Google</a>
<section id="section1"></section>
<section id="section2"></section>
<section id="section3">
<div id="autoScroll">
<div id="content"></div>
</div>
</section>

In终于想出了一个解决方案。它包括通过jQuery手动滚动页面,类似于这里提供的答案:Anchor<a>使用#时标签在chrome中不起作用

$(function() {
$(window).on('hashchange', function () {
let target = $(location.hash);
if (target.length) {
$('body')[0].scrollTop = target.offset().top;
}
});
setTimeout(function () {$(window).trigger('hashchange')}, 150);
});

我不知道为什么需要超时,但忽略它会导致页面在初始加载时根本无法滚动。

最新更新