最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ScrollIntoView breaks the overflow scroll - Stack Overflow

programmeradmin1浏览0评论

I have a nested child container and when I'm trying to scrollIntoView it breaks the parent container. I'm not able to understand why it's acting like this. Please help me out in this.
Please have a look at the code below or on jsfiddle

function moveToTop() {
  console.log('MOVE TO TOP::');
  const child = document.getElementById('child');
  child.scrollIntoView({
    behavior: "smooth"
  });
}
#parent {
  background-color: blue;
  padding: 10px;
  height: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#scroller {
  overflow: auto;
  padding: 10px;
  background-color: red;
  flex-grow: 1;
}

#child {
  height: 10000px;
  background-color: green;
}

body {
  overflow: hidden;
  color: #fff;
  font-weight: bold;
}

button {
  position: fixed;
  bottom: 20px;
  width: 140px;
  left: 20%;
  right: 0;
}
<div id="parent">
  PARENT
  <div id="something">Something</div>
  <div id="scroller">
    CHILD
    <div id="child">
      GRAND CHILD
      <button onclick="moveToTop()">Top</button>
    </div>
  </div>
</div>

I have a nested child container and when I'm trying to scrollIntoView it breaks the parent container. I'm not able to understand why it's acting like this. Please help me out in this.
Please have a look at the code below or on jsfiddle

function moveToTop() {
  console.log('MOVE TO TOP::');
  const child = document.getElementById('child');
  child.scrollIntoView({
    behavior: "smooth"
  });
}
#parent {
  background-color: blue;
  padding: 10px;
  height: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#scroller {
  overflow: auto;
  padding: 10px;
  background-color: red;
  flex-grow: 1;
}

#child {
  height: 10000px;
  background-color: green;
}

body {
  overflow: hidden;
  color: #fff;
  font-weight: bold;
}

button {
  position: fixed;
  bottom: 20px;
  width: 140px;
  left: 20%;
  right: 0;
}
<div id="parent">
  PARENT
  <div id="something">Something</div>
  <div id="scroller">
    CHILD
    <div id="child">
      GRAND CHILD
      <button onclick="moveToTop()">Top</button>
    </div>
  </div>
</div>

Share Improve this question edited Jan 29, 2021 at 12:48 deathstroke asked Jan 29, 2021 at 11:43 deathstrokedeathstroke 6037 silver badges19 bronze badges 7
  • 1 What means - "it breaks the parent container"? – s.kuznetsov Commented Jan 29, 2021 at 11:50
  • It means when you fire a scrollIntoView event the scroll breaks into parent view although the overflow was in child. If you see jsfiddle you can get a better idea about what I'm trying to say. I'm sorry for the bad english. – deathstroke Commented Jan 29, 2021 at 11:53
  • But I don't see any problem in your code. scrollIntoView works like that - scrolls to the top of the specified item. Everything is correct. What general behavior do you want to see? – s.kuznetsov Commented Jan 29, 2021 at 11:59
  • So we have a Parent, Child and Grand Child. When you click on the button, it breaks into the Parent. It should go to the top of Grand Child only. – deathstroke Commented Jan 29, 2021 at 12:06
  • I think I understand your problem. The parent block hides at the top of the window after scrolling - ibb.co/fSjKV3p. So? – s.kuznetsov Commented Jan 29, 2021 at 12:17
 |  Show 2 more ments

1 Answer 1

Reset to default 7

The whole problem is that scrollIntoView() is moving the window. But since the #parent overflow is hidden, when the window is moved, this element itself breaks. I could suggest setting a position: fixed for the #parent, which will solve your problem, but it can harm the layout in general.

Use the scroll() method. The scrolling mechanism itself is:

scroller.scroll(0, child.offsetTop - 55);

child.offsetTop - top element;

55 - distance from the top of the #parent to the top #scroller.

The transition animation must be set to css, in selector #scroller. Like that:

#scroller {
  ...
  scroll-behavior: smooth;
}

function moveToTop() {
  console.log('MOVE TO TOP::');
  const child = document.getElementById('child');
  const scroller = document.getElementById('scroller');
  scroller.scroll(0, child.offsetTop - 55);
}
#parent {
  background-color: blue;
  padding: 10px;
  height: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#scroller {
  overflow: auto;
  padding: 10px;
  background-color: red;
  flex-grow: 1;
  scroll-behavior: smooth;
}

#child {
  height: 10000px;
  background-color: green;
}

body {
  overflow: hidden;
  color: #fff;
  font-weight: bold;
}

button {
  position: fixed;
  bottom: 20px;
  width: 140px;
  left: 20%;
  right: 0;
}
<div id="parent">
  PARENT
  <div id="something">Something</div>
  <div id="scroller">
    CHILD
    <div id="child">
      GRAND CHILD
      <button onclick="moveToTop()">Top</button>
    </div>
  </div>
</div>

发布评论

评论列表(0)

  1. 暂无评论