当用户开始自己滚动时,如何防止停止 scrollIntoView?
Posted
技术标签:
【中文标题】当用户开始自己滚动时,如何防止停止 scrollIntoView?【英文标题】:How can I prevent stopping scrollIntoView when the user starts to scroll by his own? 【发布时间】:2022-01-05 22:01:15 【问题描述】:我有一个导航栏,我在其中使用scrollIntoView
始终将活动元素放在列表的中心。但是我发现当用户滚动主要内容时,它会中断/停止 scrollIntoView。它仅在用户没有滚动时才有效。你可以在这个例子中:https://jsfiddle.net/2otv6pyx/
(代码与下面相同。但是该示例在 *** 上有点错误,因为它正在滚动页面)
const first = document.querySelector('#first')
const last = document.querySelector('#last')
let atLast = false
setInterval(() =>
if (!atLast)
last.scrollIntoView(
block: "end",
behavior: "smooth"
)
atLast = true
else
first.scrollIntoView(
block: "end",
behavior: "smooth"
)
atLast = false
, 1000)
nav
position: sticky;
top: 0;
background-color: white;
nav>ul
list-style-type: none;
display: grid;
grid-auto-flow: column;
overflow-x: scroll;
nav .active
color: red
nav li
padding-right: 1rem;
p
line-height: 8rem;
<nav>
<ul>
<li id="first">Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li id="last">Sulier</li>
</ul>
</nav>
<main>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt
ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt
ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse</p>
</main>
我希望能够滚动主要内容而不停止导航栏中的动画。我怎样才能做到这一点?有没有办法强制 scrollIntoView?
我还注意到,当我向下滚动整个内容时,它会先向上滚动,然后再水平滚动。
【问题讨论】:
???? sn-p 控制了滚动并控制了我一点。不是答案,但您有两次以相同方式编写的选项对象。将选项放在变量中并将其传递给每个变量可能会很好。 小心 - 你的效果在 Safari 中不起作用 -> developer.mozilla.org/en-US/docs/Web/API/Element/… 修复它:` 行为:“平滑”,块:“最近”,内联:“开始”` 我认为您遇到的主要问题是.scrollIntoView
滚动窗口,而scrollTo
等另一种方法可以滚动特定元素。我已经做了一些测试并使其工作,但我没有时间做出正式的答案。如果它稍后仍然开放,我可以再试一次,祝你好运!即ul.scrollTo( top: 1000, left: 1000, behavior: "smooth" )
【参考方案1】:
您在代码中遇到的主要问题是 Element.scrollIntoView
方法强制窗口滚动,而实际上您只是希望 ul
元素滚动。
相反,Element.scrollTo
方法是实现目标的更好选择。这个方法只会滚动指定的元素而不是滚动窗口。这允许您在窗口中的其他位置滚动,而不会与 ul
中发生的滚动冲突。
因为我们使用的是这个方法,所以我们必须指定我们希望元素滚动多远。就像.scrollIntoView
一样,.scrollTo
接受一个选项对象。对于您的演示,left
选项是重要的修改。我们可以输入left: 0
滚动到开头,输入left: someBigNumber
滚动到末尾,但是“幻数”并不理想。能够动态决定滚动点很重要。
为了确定所需的left
值,我调用了每个元素的客户矩形,并存储了矩形提供的left
值。但是,这个left
值是从window
的角度来看的。为了抵消这个左值,我找到了包含first
和last
元素的ul
的左值,并且在将值传递给选项时,我减去了ulLeft
值。
您可能会注意到滚动效果一直向右但不是一直向左。这是因为我们不能将最后一个元素滚动到视图的开头,所以它会尽可能地停止。滚动不会一直向左,因为我们正在滚动到第一个 li 的开头,并且第一个 li 之前有空格。根据所需的效果,您也可以计算这些偏移值。
我在测试时更改的其他一些内容:
分号!在每条语句的末尾添加分号。
我没有使用setInterval
,而是选择了带有while循环和wait
辅助函数的异步函数,因为我觉得它更具可读性。
const first = document.querySelector('li:first-of-type');
const last = document.querySelector('li:last-of-type');
const ul = document.querySelector("ul");
const lastLeft = last.getBoundingClientRect().left;
const firstLeft = first.getBoundingClientRect().left;
const ulLeft = ul.getBoundingClientRect().left;
const wait = () => new Promise(r => setTimeout(r, 2000));
(async () =>
await wait();
while(true)
ul.scrollTo(
behavior: "smooth",
left: lastLeft - ulLeft
);
await wait();
ul.scrollTo(
behavior: "smooth",
left: firstLeft - ulLeft
);
await wait();
)();
nav
position: sticky;
top: 0;
background-color: white;
nav>ul
list-style-type: none;
display: grid;
grid-auto-flow: column;
overflow-x: scroll;
nav .active
color: red
nav li
padding-right: 1rem;
p
line-height: 8rem;
<nav>
<ul>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
<li>Nice</li>
<li>useScroll</li>
<li>Is</li>
<li>Sulier</li>
</ul>
</nav>
<main>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt
ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt
ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse</p>
</main>
【讨论】:
感谢您的详细解答。帮助我找出问题所在。现在可以使用了!以上是关于当用户开始自己滚动时,如何防止停止 scrollIntoView?的主要内容,如果未能解决你的问题,请参考以下文章
从 UISplitViewController 显示时,UITableViewController 自动滚动停止考虑键盘