我有一个div,只有300像素大,我希望它在页面加载时滚动到内容的底部。这个div有动态添加的内容,需要一直向下滚动。现在如果用户决定向上滚动,我不希望它跳回底部,直到用户再次向下滚动
是否有可能有一个div,将保持滚动到底部,除非用户向上滚动,当用户滚动回底部时,它需要保持自己在底部,即使添加了新的动态内容。我该怎么做呢。
我有一个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的工具来处理日常工作,所以非常欢迎评论。
其他回答
我设法把它修好了。诀窍是计算:(a)当前div用户滚动位置和(b) div滚动高度,都是在附加新元素之前。
如果a === b,则在追加新元素之前就知道用户位于底部。
let div = document.querySelector('div.scrollableBox');
let span = document.createElement('span');
span.textContent = 'Hello';
let divCurrentUserScrollPosition = div.scrollTop + div.offsetHeight;
let divScrollHeight = div.scrollHeight;
// We have the current scroll positions saved in
// variables, so now we can append the new element.
div.append(span);
if ((divScrollHeight === divCurrentUserScrollPosition)) {
// Scroll to bottom of div
div.scrollTo({ left: 0, top: div.scrollHeight });
}
基于吉姆霍尔斯的解决方案和意见。https://stackoverflow.com/a/44051405/9208887。
我额外添加了一个flex 1 1 0%的元素,以确保文本在容器未满时从顶部开始。
// just to add some numbers, so we can see the effect // the actual solution requires no javascript let num = 1001; const container = document.getElementById("scroll-container"); document.getElementById("adder").onclick = () => container.append( Object.assign(document.createElement("div"), { textContent: num++ }) ); .scroll-wrapper { height: 100px; overflow: auto; display: flex; flex-direction: column-reverse; border: 1px solid black; } .scroll-start-at-top { flex: 1 1 0%; } <div class="scroll-wrapper"> <span class="scroll-start-at-top"></span> <div id="scroll-container"> <div>1000</div> </div> </div> <button id="adder">Add Text</button>
我不能让前两个答案工作,其他答案都对我没有帮助。所以我从Reddit r/forhire和Upwork上给了三个人30美元,得到了一些非常好的答案。这个答案可以帮你省下90美元。
Justin Hundley / The Site Bros的解决方案
HTML
<div id="chatscreen">
<div id="inner">
</div>
</div>
CSS
#chatscreen {
width: 300px;
overflow-y: scroll;
max-height:100px;
}
Javascript
$(function(){
var scrolled = false;
var lastScroll = 0;
var count = 0;
$("#chatscreen").on("scroll", function() {
var nextScroll = $(this).scrollTop();
if (nextScroll <= lastScroll) {
scrolled = true;
}
lastScroll = nextScroll;
console.log(nextScroll, $("#inner").height())
if ((nextScroll + 100) == $("#inner").height()) {
scrolled = false;
}
});
function updateScroll(){
if(!scrolled){
var element = document.getElementById("chatscreen");
var inner = document.getElementById("inner");
element.scrollTop = inner.scrollHeight;
}
}
// Now let's load our messages
function load_messages(){
$( "#inner" ).append( "Test" + count + "<br/>" );
count = count + 1;
updateScroll();
}
setInterval(load_messages,300);
});
预览网站兄弟的解决方案
投资组合
莱尔梅克斯/斯维亚托斯拉夫·丘马科夫的解决方案
HTML
<div id="chatscreen">
</div>
CSS
#chatscreen {
height: 300px;
border: 1px solid purple;
overflow: scroll;
}
Javascript
$(function(){
var isScrolledToBottom = false;
// Now let's load our messages
function load_messages(){
$( "#chatscreen" ).append( "<br>Test" );
updateScr();
}
var out = document.getElementById("chatscreen");
var c = 0;
$("#chatscreen").on('scroll', function(){
console.log(out.scrollHeight);
isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 10;
});
function updateScr() {
// allow 1px inaccuracy by adding 1
//console.log(out.scrollHeight - out.clientHeight, out.scrollTop + 1);
var newElement = document.createElement("div");
newElement.innerHTML = c++;
out.appendChild(newElement);
console.log(isScrolledToBottom);
// scroll to bottom if isScrolledToBotto
if(isScrolledToBottom) {out.scrollTop = out.scrollHeight - out.clientHeight; }
}
var add = setInterval(updateScr, 1000);
setInterval(load_messages,300); // change to 300 to show the latest message you sent after pressing enter // comment this line and it works, uncomment and it fails
// leaving it on 1000 shows the second to last message
setInterval(updateScroll,30);
});
预览Sviatoslav的解决方案
投资组合
伊戈尔·鲁西诺夫的解决方案
HTML
<div id="chatscreen"></div>
CSS
#chatscreen {
height: 100px;
overflow: scroll;
border: 1px solid #000;
}
Javascript
$(function(){
// Now let's load our messages
function load_messages(){
$( "#chatscreen" ).append( "<br>Test" );
}
var out = document.getElementById("chatscreen");
var c = 0;
var add = setInterval(function() {
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
load_messages();
// scroll to bottom if isScrolledToBotto
if(isScrolledToBottom) {out.scrollTop = out.scrollHeight - out.clientHeight; }
}, 1000);
setInterval(updateScroll,30);
});
预览Igor的解决方案
投资组合
这个问题有原生的支持。
有一个叫做*. scrollintoview的方法。 在运行此方法一次之后,它将容器滚动保持在底部。 即使在容器中添加了新内容,它也会滚动到底部。
import {
AfterViewInit,
Directive,
ElementRef,
} from '@angular/core';
@Directive({
selector: '[aeScrollIntoView]',
})
export class ScrollIntoViewDirective implements AfterViewInit {
constructor(private readonly el: ElementRef<HTMLDivElement>) {}
ngAfterViewInit(): void {
this.el.nativeElement.scrollIntoView({ behavior: 'smooth' });
}
}
<div aeScrollIntoView>
Your long and dynamic content.
Whenever new content is added to this container, it scrolls to the bottom.
<div>
. cont { 高地:100px; overflow-x:隐藏; overflow-y: auto; 用金币:rotate (180deg); 方向:rtl级; text-align:向左拐; 的 申{ 溢出:隐藏; 用金币:rotate (180deg); 的 < div级= cont”> <德> < li > 0 < / li > < li > 1 < / li > < li > 2 < / li > < li > 3 < / li > < li > 4 < / li > < li > 5 < / li > < li > 6 < / li > < li > 7 < / li > < li > 8 < / li > < li > 9 < / li > < li > 10 < / li > < /德> < / div >
单击Run代码片段查看效果。(如果运行代码片段不起作用,请尝试以下方法:https://jsfiddle.net/Yeshen/xm2yLksu/3/。)
工作原理:默认情况下溢出滚动是从上到下。Transform: rotate(180deg)将此反转,因此滚动或加载动态块是从下到上的。
创意:https://blog.csdn.net/yeshennet/article/details/88880252