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

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


当前回答

这个问题有原生的支持。

有一个叫做*. 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>

其他回答

你可以用这样的东西,

var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);

这可能对你有帮助:

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;
});

Jim Hall的答案更可取,因为当你向上滚动时,它确实不会滚动到底部,它也是纯CSS。

然而,非常不幸的是,这不是一个稳定的解决方案:在chrome(可能是由于1像素的问题由dotnetCarpenter上面描述),scrollTop行为不准确的1像素,即使没有用户交互(在元素添加)。你可以设置scrollTop = scrollHeight - clientHeight,但是当另一个元素被添加时,这将保持div的位置,也就是“保持自己在底部”功能不再工作了。

所以,简而言之,添加少量Javascript(唉)将修复这个问题并满足所有要求:

类似于https://codepen.io/anon/pen/pdrLEZ this(示例由Coo),在添加一个元素到列表后,还可以执行以下操作:

container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
    container.scrollTop = container.scrollHeight - container.clientHeight;
}

29是直线的高度。

因此,当用户向上滚动半行时(如果可能的话?),Javascript将忽略它并滚动到底部。但我想这是可以忽略的。而且,它修复了Chrome 1px的东西。

基于吉姆霍尔斯的解决方案和意见。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>

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

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