【问题标题】:JQuery - Scroll and anchor to bottom of ajax-driven div unless user scrolls upJQuery - 除非用户向上滚动,否则滚动并锚定到 ajax 驱动的 div 的底部
【发布时间】:2017-07-24 23:53:11
【问题描述】:

我正在尝试滚动到 div #chat-feed 的底部,溢出设置为自动并保持在那里,除非用户向上滚动该 div 的内容。如果他们向下滚动,则 div 应该锁定到底部,并且新内容将显示在底部。

已知问题:我曾尝试使用我的代码实现 this answer,但我对 Javascript 的了解还不够,无法使其正常工作。如果来自chat-feed.php 的内容高于容器,则滚动条将停留在顶部。给出的答案似乎也不尊重从外部文件加载的内容。

关键点:新内容应该显示在底部,并且当新内容加载时,div 应该滚动到底部,除非用户已经向上滚动了一点。如果用户向下滚动,那么它应该锁定到底部并且新内容显示在底部并且可见。

<div id="chat-feed" style="height: 200px; width: 300px; overflow: auto;"></div>


<script>
$(document).ready(function(){
    setInterval(function(){
        $('#chat-feed').load("chat-feed.php").fadeIn("slow");
    }, 1000);
});
</script>

Demo link

【问题讨论】:

    标签: javascript jquery html ajax


    【解决方案1】:

    关于您链接到的问题,https://stackoverflow.com/a/21067431/1544886 有更好的实现。

    我在下面修改了该作者的代码:

    $(document).ready(function() {
    
      var out = document.getElementById("chat-feed"); // outer container of messages
      var c = 0; // used only to make the fake messages different
    
      // generate some chatter every second
      setInterval(function() {
    
        //check current scroll position BEFORE message is appended to the container
        var isScrolledToBottom = checkIfScrolledBottom();
    
        // append new mesage here
        $('#chat-feed').append("<div>Some new chat..." + c++ + "</div>").fadeIn("slow");
    
        // scroll to bottom if scroll position had been at bottom prior
        scrollToBottom(isScrolledToBottom);
    
      }, 1000);
    
      function checkIfScrolledBottom() {
        // allow for 1px inaccuracy by adding 1
        return out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
      }
    
      function scrollToBottom(scrollDown) {
        if (scrollDown)
          out.scrollTop = out.scrollHeight - out.clientHeight;
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="chat-feed" style="height: 150px; width: 300px; overflow: auto;"></div>

    更新

    JQuery 的.load() 函数删除关联元素(chat-feed)并重新添加。这意味着out 变量指向旧的已删除元素,而不是新元素。解决方案是在执行.load() 后更新out 变量:

    $('#chat-feed').load("chat-feed.php").fadeIn("slow");
    out = document.getElementById("chat-feed"); // outer container of messages
    

    【讨论】:

    • 我已经做到了这一点,但是当从 chat-feed.php 加载内容时,所需的效果似乎不起作用。此外,如果来自chat-feed.php 的内容已经比容器高,则滚动条位于顶部,您必须手动向下滚动。文件chat-feed.php 只是一堆&lt;p&gt;hey&lt;/p&gt; 行。你能用外部加载的内容进行验证,然后在文件中添加一行,看看它是否按需要滚动?
    • 添加了如何处理 .load() 的说明
    • 在您的帮助和一些戳戳和刺激下,我让它大部分工作。滚动条的初始位置停留在顶部所以我不得不在脚本底部添加一个延迟触发器来强制滚动条到容器的底部 div setTimeout(function() { $("#chat-feed").scrollTop($("#chat-feed")[0].scrollHeight);}, 1500); 有没有更优雅的方法来强制滚动条到脚本初始执行时的底部?
    • 我早些时候在本地使用.load() 使用比容器大的 html 文件对其进行了测试。它对我来说效果很好(在 .load() 之后使用out = ... 添加,如更新的答案中所述),所以不明白为什么它不适合你。然而,我确实使用了最新版本的 jQuery。至于您的查询,最好使用:out = document.getElementById("chat-feed");scrollToBottom(true);
    • 您也可以尝试删除fadein()。我不记得我是否将其包含在测试中,但可能没有
    猜你喜欢
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多