admin管理员组文章数量:1303345
I have two overflowing elements on the page, I would like to call ScrollIntoView
at the same time for child elements within both of them.
The following works in Firefox, but not Chrome. Is this a bug?
const button = document.querySelector('button');
const one = document.querySelector('.one');
const two = document.querySelector('.two');
button.addEventListener('click', () => {
one.scrollIntoView({ block: 'center', behavior: 'smooth' });
two.scrollIntoView({ block: 'center', behavior: 'smooth' });
});
body {
text-align: center;
}
#container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
width: 100%;
height: 130px;
}
#container > div {
max-height: 200px;
overflow-y: auto;
border: 1px solid black;
}
button {
font-size: 1.5rem;
margin: 0.5rem auto;
}
<div id="container">
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="one">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="two">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
</div>
<button>click to scroll</button>
I have two overflowing elements on the page, I would like to call ScrollIntoView
at the same time for child elements within both of them.
The following works in Firefox, but not Chrome. Is this a bug?
const button = document.querySelector('button');
const one = document.querySelector('.one');
const two = document.querySelector('.two');
button.addEventListener('click', () => {
one.scrollIntoView({ block: 'center', behavior: 'smooth' });
two.scrollIntoView({ block: 'center', behavior: 'smooth' });
});
body {
text-align: center;
}
#container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
width: 100%;
height: 130px;
}
#container > div {
max-height: 200px;
overflow-y: auto;
border: 1px solid black;
}
button {
font-size: 1.5rem;
margin: 0.5rem auto;
}
<div id="container">
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="one">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="two">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
</div>
<button>click to scroll</button>
Share
asked Mar 11, 2021 at 16:22
MattMatt
10.4k5 gold badges37 silver badges68 bronze badges
1
-
1
I gave you the solution using
scrollTo()
. Do you have any questions or requests? Is there anything that needs to be done in my code? And try to avoid using ScrollIntoView. Since there are disadvantages. For instance - stackoverflow./questions/65953805/… – s.kuznetsov Commented Mar 12, 2021 at 5:10
4 Answers
Reset to default 4Better use the normal scrollTo()
scrolling method with smooth scroll.
I had to use a for {}
, since I was referring to a collection of scrollable divs inside #container
:
const container_div = document.querySelectorAll("#container > div");
Also, I have specified the same class for both <h1>
control tags:
const text = document.querySelectorAll(".boo");
const button = document.querySelector("button");
const container_div = document.querySelectorAll("#container > div");
const text = document.querySelectorAll(".boo");
button.addEventListener("click", () => {
for (i = 0; i < container_div.length; i++) {
container_div[i].scrollTo({ top: text[i].offsetTop, behavior: "smooth" });
}
});
body {
text-align: center;
}
#container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
width: 100%;
height: 130px;
}
#container > div {
max-height: 200px;
overflow-y: auto;
border: 1px solid black;
}
button {
font-size: 1.5rem;
margin: 0.5rem auto;
}
<div id="container">
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="boo">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
<div>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1 class="boo">Boo!</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
<h1>...</h1>
</div>
</div>
<button>click to scroll</button>
Seems like Chrome blocks 2 smooths scrolls at the same time. Change behavior into auto and scroll will work.
I solved this issue by setting different timeouts. In my example i had two ponents. Each firing at 500 and 1000 ms.
setTimeout(() => {
scrollToCard(this.selectedId);
}, this.type === 'first' ? 500 : 1000);
scrollToCard(id: string) {
const selected = document.getElementById(
'scrollTo-' + id + '-' + this.type
);
if (selected) {
selected.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start',
});
}
}
As the answers suggests above that Chrome blocks 2 smooths scrolls at the same time. I fixed it by only triggering the second scroll after a small timeout of 300ms giving enough time for the first smooth scroll to finish. This was achieved by using setTimeOut.
setTimeout(() => {
myRef?.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 300);
Although this works for my use case, you could also try setting the behaviour: auto
for the other scroll for it to work simultaneously.
本文标签: javascriptWhy doesn39t ScrollIntoView work on two simultaneous elementsStack Overflow
版权声明:本文标题:javascript - Why doesn't `ScrollIntoView` work on two simultaneous elements? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741704954a2393504.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论