滚动到 div 的底部?

1067

我正在使用Ajax请求创建一个聊天,我试图让消息div滚动到底部,但没有成功。

我将所有内容都装进了这个div中:

#scroll {
    height:400px;
    overflow:scroll;
}

是否有一种使用JS默认情况下保持滚动到底部的方法?

在ajax请求后是否有一种保持滚动到底部的方法?


在许多情况下,这可以通过仅使用 CSS实现。请参阅此答案 - ashleedawg
你可以简单地使用Jquery来实现这个功能: code $(document).ready(function() { var chatMessagesDiv = $('#scroll'); chatMessagesDiv.scrollTop(chatMessagesDiv[0].scrollHeight); }); - Ravindu Lokumanna
35个回答

10
如果你的项目面向现代浏览器,你现在可以使用CSS Scroll Snap来控制滚动行为,例如将任何动态生成的元素保持在底部。

    .wrapper > div {
        background-color: white;
        border-radius: 5px;
        padding: 5px 10px;
        text-align: center;
        font-family: system-ui, sans-serif;
    }

    .wrapper {
        display: flex;
        padding: 5px;
        background-color: #ccc;
        border-radius: 5px;
        flex-direction: column;
        gap: 5px;
        margin: 10px;
        max-height: 150px;

        /* Control snap from here */
        overflow-y: auto;
        overscroll-behavior-y: contain;
        scroll-snap-type: y mandatory;
    }

    .wrapper > div:last-child {
        scroll-snap-align: start;
    }
<div class="wrapper">
    <div>01</div>
    <div>02</div>
    <div>03</div>
    <div>04</div>
    <div>05</div>
    <div>06</div>
    <div>07</div>
    <div>08</div>
    <div>09</div>
    <div>10</div>
</div>


4
请注意,这将使动态生成的元素保持在底部,因此如果您向上滚动,包装器将自动向下滚动到底部。 - Raffi

10

Java Script:

document.getElementById('messages').scrollIntoView(false);

将滚动到内容的最后一行。


8
你可以使用HTML DOM的scrollIntoView方法来实现这个功能:
你可以像这样使用scrollIntoView方法:
var element = document.getElementById("scroll");
element.scrollIntoView();

8

不需要 JavaScript 的方法(2023年)

这里有一个不需要任何 JavaScript,而是使用纯(Flexbox)CSS 的方法。我在这里更详细地解释了这个方法。

诀窍是将项目放在“content”元素中,该元素包装在column-reverse flexbox元素内,充当“滚动条”。因为项目位于另一个(“content”)容器中,所以它们不会被“翻转”,而是始终对齐到底部。实际上,每次添加内容时都会使滚动条滚动到底部。

此方法的优点

除了不依赖 JavaScript 之外,这种方法的一个重要优点是,当用户开始滚动列表时,滚动位置保持固定,直到用户滚动到的位置。这样可以防止新项添加时出现令人讨厌的内容跳动。一旦用户再次滚回底部,更新列表时列表将保持滚动到底部。

Breakdown, click for demo

演示

注意:下面演示中的JavaScript仅用于演示本身(添加项目并查看发生了什么)。

let scrollerContent = document.getElementById('scrollerContent');

document.getElementById('addItems').addEventListener('click', function() {
  let newChild = scrollerContent.lastElementChild.cloneNode(true);
  newChild.innerHTML = "Item " + (scrollerContent.children.length + 1);
  scrollerContent.appendChild(newChild);
});
.scroller {
  overflow: auto;
  height: 100px;
  display: flex;
  flex-direction: column-reverse;
}

.scroller .scroller-content .item {
  height: 20px;
  transform: translateZ(0); /* fixes a bug in Safari iOS where the scroller doesn't update */
}
<div class="scroller">
  <div class="scroller-content" id="scrollerContent">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
    <div class="item">Item 7</div>
    <div class="item">Item 8</div>
    <div class="item">Item 9</div>
    <div class="item">Item 10</div>
  </div>
</div>
<br/><br/>
<button id="addItems">Add more items</button>


1
这是一个很有启发性和酷炫的技巧。完美运行。 - Abdul Rafay Shaikh
我正在使用这个技巧来娱乐和获利,但是我不知道如何在我真正想要时使内容跳转。这是一个聊天界面,所以当有新消息时,页面不应自动滚动到底部,这一点很好。但是当我自己发送消息时,我该如何将页面滚动到底部呢? - cassepipe

7

Javascript或jQuery:

var scroll = document.getElementById('messages');
   scroll.scrollTop = scroll.scrollHeight;
   scroll.animate({scrollTop: scroll.scrollHeight});

CSS:

 .messages
 {
      height: 100%;
      overflow: auto;
  }

6

我觉得这非常有帮助,谢谢。

对于Angular 1.X的开发者们:

angular.module('myApp').controller('myController', ['$scope', '$document',
  function($scope, $document) {

    var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
    overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;

  }
]);

由于在Angular中,jQuery元素与HTML DOM元素的包装有些令人困惑,因此需要进行翻译。

对于聊天应用程序,我发现在加载聊天后执行此任务很有用,您可能还需要添加短暂的超时。


5
我遇到了同样的问题,但是还有一个额外的限制:我无法控制向滚动容器添加新元素的代码。我在这里找到的所有例子都不能让我做到这一点。下面是我最终使用的解决方案。
它使用变异观察器https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver),因此仅可在现代浏览器上使用(虽然存在polyfills)。
因此,基本上代码就是这样做的:
var scrollContainer = document.getElementById("myId");

// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {

  // Compute sum of the heights of added Nodes
  var newNodesHeight = mutations.reduce(function(sum, mutation) {
      return sum + [].slice.call(mutation.addedNodes)
        .map(function (node) { return node.scrollHeight || 0; })
        .reduce(function(sum, height) {return sum + height});
  }, 0);

  // Scroll to bottom if it was already scrolled to bottom
  if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
    scrollContainer.scrollTop = scrollContainer.scrollHeight;
  }

});

// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});

我制作了一个示例fiddle来演示这个概念: https://jsfiddle.net/j17r4bnk/

如何获取动态ID?例如在<div class="abc"><div data-bind=attr : {'id': myId } ></div></div>中,myId是一个变量。我该如何在脚本中访问这个ID? - Irfan Y
我不太确定我理解你的问题。在我的例子中,“myId”是滚动容器的ID。您想创建多个用户可以滚动的区域吗? - Benkinass

5

使用jQuery,scrollTop被用来设置任何给定元素的滚动条的垂直位置。还有一个很好的jquery scrollTo插件用于使用动画和不同选项进行滚动(演示)。

var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;

如果你想使用jQuery的animate方法在向下滚动时添加动画效果,请查看以下片段:

var myDiv = $("#div_id").get(0);
myDiv.animate({
    scrollTop: myDiv.scrollHeight
  }, 500);

5

和你一样,我正在构建一个聊天应用,并希望最新的消息自动滚动到视图中。对于我来说,以下方法是有效的:

//get the div that contains all the messages
let div = document.getElementById('message-container');

//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });

4

您还可以使用jQuery将动画附加到文档的html,body,方法如下:

$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);

这将导致平滑滚动到ID为"div-id"的

元素的顶部。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接