除非用户向上滚动,否则将溢出 div 滚动到底部

IT技术 javascript jquery html css scroll
2021-02-06 20:53:31

我有一个只有 300 像素大的 div,我希望它在页面加载时滚动到内容的底部。这个 div 有动态添加的内容,需要一直向下滚动。现在,如果用户决定向上滚动,我不希望它跳回底部,直到用户再次向下滚动

是否有可能让 div 保持滚动到底部,除非用户向上滚动,并且当用户滚动回底部时,即使添加了新的动态内容,它也需要将自身保持在底部。我将如何创建这个。

6个回答

我只能使用 CSS 来实现它。

诀窍是使用display: flex;flex-direction: column-reverse;

浏览器将底部视为顶部。假设您的目标浏览器支持 support flex-box,唯一需要注意的是标记必须以相反的顺序排列。

这是一个工作示例。https://codepen.io/jimbol/pen/YVJzBg

不幸的是,此解决方案似乎不适用于 Firefox :(
2021-03-25 20:53:31
可能是最好的解决方案,因为它不需要 javascript。
2021-03-28 20:53:31
您可以通过添加额外的包装器并应用overflow:auto; display:flex; flex-direction:column-reverse;到外部包装器而不是内部包装器来避免需要反转内容
2021-04-01 20:53:31
@NathanArthur 事实上,如果你只是在容器下添加一个 div 来取消反转所有内容:codepen.io/anon/pen/pdrLEZ
2021-04-04 20:53:31
现在是 2020 年 10 月。我已经检查过它也在 Firefox 上运行。感谢您的快速解决方案。
2021-04-11 20:53:31

这可能会帮助您:

var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;

[编辑],匹配评论...

function updateScroll(){
    var element = document.getElementById("yourDivID");
    element.scrollTop = element.scrollHeight;
}

每当添加内容时,调用函数 updateScroll(),或设置一个计时器:

//once a second
setInterval(updateScroll,1000);

如果您只想在用户未移动时更新:

var scrolled = false;
function updateScroll(){
    if(!scrolled){
        var element = document.getElementById("yourDivID");
        element.scrollTop = element.scrollHeight;
    }
}

$("#yourDivID").on('scroll', function(){
    scrolled=true;
});
这很好地在页面加载时将其滚动到底部,但是除非用户向上滚动,否则在添加动态内容时我需要它保持在底部。
2021-03-22 20:53:31
@ethancrist 但是,您别无选择……耸耸肩。
2021-04-01 20:53:31
@TvE 我们不能添加支持吗?
2021-04-05 20:53:31
糟糕的解决方案。没有理由setInterval为这个轻微的问题添加一个
2021-04-05 20:53:31
据我所知,当用户滚动回底部时,这不会重新启用动态滚动......
2021-04-08 20:53:31

我刚刚实现了这个,也许你可以使用我的方法。

假设我们有以下 HTML:

<div id="out" style="overflow:auto"></div>

然后我们可以检查它是否滚动到底部:

var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;

scrollHeight为您提供元素的高度,包括由于溢出而导致的任何不可见区域。clientHeight为您提供 CSS 高度或换句话说,元素的实际高度。这两种方法都返回没有 的高度margin,所以你不必担心。scrollTop为您提供垂直滚动的位置。0 是顶部,max 是元素的滚动高度减去元素本身的高度。使用滚动条时,将滚动条一直拖到底部可能很困难(对我来说是在 Chrome 中)。所以我抛出了 1px 的误差。因此,isScrolledToBottom将真实的,即使滚动条从底部1px的。您可以将其设置为您认为合适的任何内容。

那么只需将元素的 scrollTop 设置为底部即可。

if(isScrolledToBottom)
    out.scrollTop = out.scrollHeight - out.clientHeight;

我为你制作了一个小提琴来展示这个概念:http : //jsfiddle.net/dotnetCarpenter/KpM5j/

编辑:添加了代码片段以阐明何时isScrolledToBottomtrue

将滚动条粘到底部

const out = document.getElementById("out")
let c = 0

setInterval(function() {
    // allow 1px inaccuracy by adding 1
    const isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1

    const newElement = document.createElement("div")

    newElement.textContent = format(c++, 'Bottom position:', out.scrollHeight - out.clientHeight,  'Scroll position:', out.scrollTop)

    out.appendChild(newElement)

    // scroll to bottom if isScrolledToBottom is true
    if (isScrolledToBottom) {
      out.scrollTop = out.scrollHeight - out.clientHeight
    }
}, 500)

function format () {
  return Array.prototype.slice.call(arguments).join(' ')
}
#out {
    height: 100px;
}
<div id="out" style="overflow:auto"></div>
<p>To be clear: We want the scrollbar to stick to the bottom if we have scrolled all the way down. If we scroll up, then we don't want the content to move.
</p>

@luskwater 你能提供一个 fsfiddle 来解决你的问题吗?我不明白out.scrollHeight - out.clientHeight <= out.scrollTop + 1. 您是否在 CSS 中使用填充?
2021-03-22 20:53:31
这就是我一直在寻找的。而且,这是 OP 提出的问题的答案。感谢 dotnetCarperter。
2021-03-25 20:53:31
@dotnetCarpenter:在我看来好像你需要if(!isScrolledToBottom):测试对我来说是错误的(并且在修复它之前没有在我的代码中工作)。
2021-03-27 20:53:31
这实际上是完成所述问题的唯一解决方案。并且应该被标记为正确答案。
2021-04-03 20:53:31
也许我很困惑,但不应该是“if (!isScrolledToBottom)”和“不是”吗?添加 not 似乎使它满足 OP 的要求。
2021-04-11 20:53:31

在 2020 年,您可以使用css snap,但在 Chrome 81 之前,布局更改不会触发 re-snap纯 css chat ui可在 Chrome 81 上运行,您也可以查看Can I use CSS snap

如果可见,此演示将捕捉最后一个元素,滚动到底部以查看效果。

.container {
  overflow-y: scroll;
  overscroll-behavior-y: contain;
  scroll-snap-type: y proximity;
}

.container > div > div:last-child {
  scroll-snap-align: end;
}

.container > div > div {
  background: lightgray;
  height: 3rem;
  font-size: 1.5rem;
}
.container > div > div:nth-child(2n) {
  background: gray;
}
<div class="container" style="height:6rem">
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
</div>

在此处输入图片说明

编辑

使用scroll-snap-type: y proximity;,向上滚动更容易。

这值得一枚奖牌。正是我要找的:)
2021-03-13 20:53:31
它适用于 Firefox 79,但前提是您使用滚动条滚动,如果您使用鼠标滚轮,它不会触发回弹。
2021-03-18 20:53:31
接近范围取决于可滚动高度。如果您的聊天视图比 2 或 3 个聊天气泡高,当您向上滚动多达 2 或 3 条消息时,它会再次弹回到末尾(除非您滚动数百个像素),这使得此方法无法使用。共享代码段起作用的原因是视图高度太小。
2021-03-23 20:53:31
@aatifshaikh 我更新了答案,现在您可以更轻松地向上滚动。
2021-04-03 20:53:31
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);

现场演示:http : //jsfiddle.net/KGfG2/

这很好地在页面加载时将其滚动到底部,但是除非用户向上滚动,否则在添加动态内容时我需要它保持在底部。
2021-03-21 20:53:31
这完美地工作。我正在更新动态内容,滚动始终位于底部。
2021-04-01 20:53:31
这仅适用于具有固定高度的 div。不适用于可变 div 高度
2021-04-03 20:53:31