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

是否有可能有一个div,将保持滚动到底部,除非用户向上滚动,当用户滚动回底部时,它需要保持自己在底部,即使添加了新的动态内容。我该怎么做呢。


当前回答

我试着用Bootstrap 5来做同样的事情。我正在编写的页面是一个单窗口html工具,我想要两列具有可滚动内容,其中一列需要反向,因为它是一个日志(另一列不太可能滚动,除非故意这么做)。列表和它们的标题也是底部锚定的,我很难让标题保持在一个灵活的可滚动列表的顶部。

多亏了上面的例子,我才能够找出我所缺少的内容并获得正确的类类型。

下面是完整的例子。在我实际的应用程序中,有其他两个类mh-100 col overflow-auto的第三列,不需要内部行/列,因为没有标题贴在顶部(如果视口太小,它只会正常滚动)。列表有一个ID,我使用它来选择并添加到它们前面或删除顶部元素(这是反向列表中的bottom <li>项)。

这里提供了一个较小的版本:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <div class="vh-100 w-75 container-fluid"> <h1>2nd Level Scrolling Example</h1> <div class="h-75 row align-items-end"> <div class="mh-100 col d-flex flex-column"> <div class="row align-items-end"> <div class="col"><h3>Normal scroll list, grow on top</h3></div> </div> <div class="row align-items-end overflow-auto"> <div class="mh-100 col"> <ul class="list-group"> <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut</li> <li>tortor eu ex tincidunt pretium non eu nisl. Ut eu libero ac velit</li> <li>ultricies dapibus. Donec id augue scelerisque, gravida est ut,</li> <li>commodo sapien. Interdum et malesuada fames ac ante ipsum primis</li> <li>in faucibus. Suspendisse volutpat fermentum finibus. Cras egestas</li> <li>tempor tempor. Suspendisse potenti. Mauris ac tellus ultrices lectus</li> <li>accumsan pellentesque. Nullam semper, nisi nec euismod ultrices, leo</li> <li>sem bibendum sapien, in rutrum sapien massa id mi.</li> </ul> </div> </div> </div> <div class="mh-100 col d-flex flex-column"> <div class="row align-items-end"> <div class="col"><h3>Reverse scroll list, grow on bottom</h3></div> </div> <div class="row align-items-end d-flex flex-column-reverse overflow-auto"> <div class="mh-100 col"> <ul class="list-group"> <li>sem bibendum sapien, in rutrum sapien massa id mi.</li> <li>accumsan pellentesque. Nullam semper, nisi nec euismod ultrices, leo</li> <li>tempor tempor. Suspendisse potenti. Mauris ac tellus ultrices lectus</li> <li>in faucibus. Suspendisse volutpat fermentum finibus. Cras egestas</li> <li>commodo sapien. Interdum et malesuada fames ac ante ipsum primis</li> <li>ultricies dapibus. Donec id augue scelerisque, gravida est ut,</li> <li>tortor eu ex tincidunt pretium non eu nisl. Ut eu libero ac velit</li> <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut</li> </ul> </div> </div> </div> </div> </div>

如果你的视口高度小于整体内容,标题应该位于列表的顶部,而所有内容都位于页面的底部(实际上是视口高度的75%,但在这个例子中,标题并没有占据它设计的空间)。

注:我不是一个真正的web开发人员,只是编写一些方便的基于html的工具来处理日常工作,所以非常欢迎评论。

其他回答

这可能对你有帮助:

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;
});
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);

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

$('#div1').scrollTop($('#div1')[0].scrollHeight);

Or animated:

$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);

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

假设我们有以下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 gives you the height of the element, including any non visible area due to overflow. clientHeight gives you the CSS height or said in another way, the actual height of the element. Both methods returns the height without margin, so you needn't worry about that. scrollTop gives you the position of the vertical scroll. 0 is top and max is the scrollHeight of the element minus the element height itself. When using the scrollbar it can be difficult (it was in Chrome for me) to get the scrollbar all the way down to the bottom. so I threw in a 1px inaccuracy. So isScrolledToBottom will be true even if the scrollbar is 1px from the bottom. You can set this to whatever feels right to you.

然后,只需将元素的scrollTop设置为底部即可。

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

我已经为你做了一个小提琴的概念:http://jsfiddle.net/dotnetCarpenter/KpM5j/

编辑: 增加了代码片段以澄清当isScrolledToBottom为真时。

Stick scrollbar to bottom 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>

我发现最友好的解决方案是将滚动-快照-对齐方法与少量Javascript结合起来。前一种解决方案本身的问题是,抓拍太强了,你必须滚动很远才能摆脱它。

相反,我们可以在容器滚动到底部时使用捕捉动态,然后在用户向上滚动超过某个阈值时禁用它。

这个解决方案还有一个额外的好处,那就是它是一个渐进的增强:如果用户禁用了Javascript,它就会退回到只使用css的方法。

const container = document.getElementById("container"); const snap = document.getElementById("snap"); // Scroll the view to the bottom once initially container.scrollTop = container.scrollHeight; container.addEventListener("scroll", (event) => { const target = event.currentTarget; const scroll = target.scrollTop; const maxScroll = target.scrollHeight - target.clientHeight; const threshold = 50; // px isScrollBottomedOut = maxScroll - scroll < threshold; // If the user scrolls up more than the threshold, disable snapping // If the user scrolls down again, reenable snapping snap.style.display = isScrollBottomedOut ? "block" : "none"; }); #container { width: 200px; height: 500px; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; -ms-scroll-chaining: none; overscroll-behavior: contain; -ms-scroll-snap-type: y proximity; scroll-snap-type: y proximity; border: 2px solid black; } #snap { scroll-snap-align: end; } <div id="container"> <ol> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> </ol> <!-- This is the snapping target, if visible --> <div id="snap"></div> </div>