在Chrome嵌套滚动中更改数据时防止页面滚动

时间:2019-04-24 15:07:44

标签: javascript html css google-chrome

我在页面上有一个固定大小的元素,该元素带有“溢出:滚动”,其内容经常更改。 我希望此元素内部发生的更改会影响此元素的滚动,但不会影响页面滚动。

但是,当此元素位于页面顶部时,页面本身开始滚动。我该如何预防?

要重现此行为(我在chrome中有此问题,但Firefox可以正常工作):

  1. 打开https://jsfiddle.net/hd2Ltmu0/2/
  2. 开始将页面滚动到灰色元素的中心
  3. 稍等片刻,页面滚动将向上移动

代码示例:

from module import name1, name2

3 个答案:

答案 0 :(得分:1)

一种骇人听闻的解决方案是在添加内容之前存储滚动条的值,并在之后使用它:

setInterval(function() {
 var s= $(window).scrollTop();
 $('.scrollable').children().first().remove();
 $('.scrollable').append('<div>'+(Date.now())+'</div>');
 $(window).scrollTop(s);
}, 1000);

;
.demo {
  font-size: 24px;
}

.scrollable {
  height: 300px;
  overflow-y: scroll;
  background: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="demo">
  String<br>
  String<br>
  String<br>
  String<br>
  <div class="scrollable">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
    <div>11</div>
    <div>12</div>
    <div>13</div>
    <div>14</div>
    <div>15</div>
</div>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
  String<br>
</div>

答案 1 :(得分:0)

之所以会这样,是因为您从DOM中删除了元素,然后添加了新元素,因此您改变了元素的高度一秒钟,页面就滚动了。

您应该替换该元素,而不是将其删除。

例如-逻辑上这不是您想要的:

setInterval(function() {
 $('.scrollable').children().first().replaceWith('<div>'+(Date.now())+'</div>');
}, 1000);

仅更改元素而不会更改高度或window.offset

答案 2 :(得分:0)

最后我添加了一个宽度为1px的空div。似乎chrome从顶部找到了第一个元素,并相对于该元素移动了滚动条。但是我的解决方案很笨拙,在任何规格中我都找不到这种行为的描述。

<body>
    <div style="height: 300px; opacity: 0; width: 1px; float: left;">
    </div>
    <div style="overflow-y: scroll;height: 300px">
        Content that changes often
    </div>
    Content that should not move even the upper block is changed
</body>

https://jsfiddle.net/y3vtued6/