【问题标题】:Prevent page scroll when data changes in nested scroll in chromechrome中嵌套滚动中的数据更改时防止页面滚动
【发布时间】:2019-09-13 22:34:45
【问题描述】:

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

但是当这个元素放在页面顶部时,页面本身就开始滚动了。我怎样才能防止这种情况发生?

重现这种行为(我在 chrome 中遇到了这个问题,但 Firefox 可以正常工作):

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

代码示例:

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

【问题讨论】:

    标签: javascript html css google-chrome


    【解决方案1】:

    一个 hacky 解决方案是在添加内容之前存储滚动的值并在之后使用它:

    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>

    【讨论】:

      【解决方案2】:

      发生这种情况是因为您从 DOM 中删除元素 - 然后添加新元素 - 以便您改变元素的高度一秒钟,页面是滚动的。

      你应该替换元素而不是删除它。

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

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

      只会改变元素而不改变高度或window.offset

      【讨论】:

      • 但是为什么更改元素的内容会使页面滚动,因为该元素具有固定的高度? (请注意,它只发生在 chrome 上)
      • 是的,在这个演示中,我可以通过重用现有的 DOM 元素来实现。但在真正的应用程序中我不能因为动画
      【解决方案3】:

      最后我添加了一个宽度为 1 像素的空 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/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 2016-07-17
        • 1970-01-01
        相关资源
        最近更新 更多