自动向下滚动聊天 div
Posted
技术标签:
【中文标题】自动向下滚动聊天 div【英文标题】:Automatically scroll down chat div 【发布时间】:2014-10-19 18:37:56 【问题描述】:我有这段代码,用来加载聊天
function getMessages(letter)
var div = $('#messages');
$.get('msg_show.php', function (data)
div.html(data);
);
setInterval(getMessages, 100);
我必须添加什么,以便在页面加载时自动向下滚动 #messages
div,并在每个新的聊天帖子中再次滚动?
这不起作用:
function getMessages(letter)
var div = $('#messages');
$.get('msg_show.php', function (data)
div.html(data);
$('#messages').scrollTop($('#messages')[0].scrollHeight);
);
setInterval(getMessages, 100);
【问题讨论】:
如果元素的 ID 是messages
,则应该是 document.getElementById('messages')
(注意缺少的 #
)。
对不起,我实际上没有#。
【参考方案1】:
让我们先回顾一些关于滚动的有用概念:
scrollHeight:容器总大小。 scrollTop: 用户滚动的数量。 clientHeight:用户看到的容器数量。什么时候应该滚动?
用户首次加载消息。 新消息已到达,您位于滚动底部(当用户向上滚动以阅读以前的消息时,您不希望强制滚动)。以编程方式:
if (firstTime)
container.scrollTop = container.scrollHeight;
firstTime = false;
else if (container.scrollTop + container.clientHeight === container.scrollHeight)
container.scrollTop = container.scrollHeight;
完整的聊天模拟器(使用 JavaScript):
https://jsfiddle.net/apvtL9xa/
const messages = document.getElementById('messages');
function appendMessage()
const message = document.getElementsByClassName('message')[0];
const newMessage = message.cloneNode(true);
messages.appendChild(newMessage);
function getMessages()
// Prior to getting your messages.
shouldScroll = messages.scrollTop + messages.clientHeight === messages.scrollHeight;
/*
* Get your messages, we'll just simulate it by appending a new one syncronously.
*/
appendMessage();
// After getting your messages.
if (!shouldScroll)
scrollToBottom();
function scrollToBottom()
messages.scrollTop = messages.scrollHeight;
scrollToBottom();
setInterval(getMessages, 100);
#messages
height: 200px;
overflow-y: auto;
<div id="messages">
<div class="message">
Hello world
</div>
</div>
【讨论】:
2019 年 1 月 16 日,现在一直自动向下滚动 如果您的容器具有非整数高度,您可能需要使用container.scrollTop + container.clientHeight >= container.scrollHeight
作为测试。
我现在无法向上滚动【参考方案2】:
不知道 HTML 代码很难说,但我假设您的 div 没有设置高度和/或不允许溢出(例如通过 CSS height: 200px; overflow: auto
)。
我在 jsfiddle 上做了一个工作示例:http://jsfiddle.net/hu4zqq4x/
我在一个 div 中创建了一些虚拟的 HTML 标记,它 a) 溢出并且 b) 具有设定的高度。 滚动是通过调用函数完成的
function getMessages(letter)
var div = $("#messages");
div.scrollTop(div.prop('scrollHeight'));
,在这种情况下,在“documentReady”上一次。
prop('scrollHeight')
将访问匹配元素集中第一个元素的属性值。
【讨论】:
【参考方案3】:在 JQuery 中追加后,只需添加这一行
<script>
$("#messages").animate( scrollTop: 20000000 , "slow");
</script>
【讨论】:
【参考方案4】:你需要做的就是把它分成两个div。一个溢出设置为滚动,一个内部用于保存文本,这样你就可以得到它的外部大小。
<div id="chatdiv">
<div id="textdiv"/>
</div>
textdiv.html("");
$.each(chatMessages, function (i, e)
textdiv.append("<span>" + e + "</span><br/>");
);
chatdiv.scrollTop(textdiv.outerHeight());
你可以在这里查看一个 jsfiddle:http://jsfiddle.net/xj5c3jcn/1/
显然,您不想每次都重建整个文本 div,因此请谨慎对待 - 只是一个示例。
【讨论】:
【参考方案5】:如果你只是滚动高度,当用户想要查看他之前的消息时会出现问题。所以你需要做一些事情,当新消息到来时只有代码。使用 jquery 最新版本。 1.在这里我检查了消息加载前的高度。 2.再次检查新高度。 3.如果高度不同,只有那一次它会滚动,否则它不会滚动。 4.不在if条件下你可以放任何铃声或你需要的任何其他功能。将在新消息到来时播放。谢谢
var oldscrollHeight = $("#messages").prop("scrollHeight");
$.get('msg_show.php', function(data)
div.html(data);
var newscrollHeight = $("#messages").prop("scrollHeight"); //Scroll height after the request
if (newscrollHeight > oldscrollHeight)
$("#messages").animate(
scrollTop: newscrollHeight
, 'normal'); //Autoscroll to bottom of div
【讨论】:
终于找到了一个对我有用的解决方案,谢谢:)【参考方案6】:简单的解决方案:
1 - 放置在消息的底部(内部)
<a href="#" class="d-none" id="focus-bottom"></a>
2 - 收到新消息时:
function getMessages (letter)
var div = $('#messages');
$.get('msg_show.php', function(data)
div.html(data);
$('#focus-bottom').focus();
$('#focus-box-message').focus(); / * FOCUS YOUR TEXTAREA * /
);
setInterval(getMessages, 100);
【讨论】:
【参考方案7】:不必混合使用 jquery 和 javascript。像这样使用,
function getMessages(letter)
var message=$('#messages');
$.get('msg_show.php', function(data)
message.html(data);
message.scrollTop(message[0].scrollHeight);
);
setInterval(function()
getMessages("letter");
, 100)
将scrollTop()
放入get()
方法中。
你也错过了getMessage
方法调用中的一个参数..
【讨论】:
与问题没有直接关系,但反复使用$('#messages')
一遍又一遍地查询相同的元素会对性能产生负面影响——可能还会影响可读性。甚至可以在getMessages
函数之外选择元素。
你是对的。我已经编辑了答案。但是在 getmessage 函数之外选择该元素没有任何意义。因为他需要在收到新消息后向下滚动到底部。所以它应该只在那个方法里面..【参考方案8】:
我在实验的时候发现了这个非常简单的方法:将scrollTo
设置为div的高度。
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
【讨论】:
【参考方案9】: var l = document.getElementsByClassName("chatMessages").length;
document.getElementsByClassName("chatMessages")[l-1].scrollIntoView();
这应该可以工作
【讨论】:
假设您的包含聊天消息的聊天框不在视图中,那么这将滚动整个页面并将聊天框也显示在视图中。不是你想要的。【参考方案10】:由于我不是 js 大师,但我自己编写代码来检查用户是否处于底部。 如果用户位于底部,则聊天页面将自动滚动显示新消息。 如果用户向上滚动页面将不会自动滚动到底部..
JS代码-
var checkbottom;
jQuery(function($)
$('.chat_screen').on('scroll', function()
var check = $(this).scrollTop() + $(this).innerHeight() >= $(this)
[0].scrollHeight;
if(check)
checkbottom = "bottom";
else
checkbottom = "nobottom";
)
);
window.setInterval(function()
if (checkbottom=="bottom")
var objDiv = document.getElementById("chat_con");
objDiv.scrollTop = objDiv.scrollHeight;
, 500);
html代码-
<div id="chat_con" class="chat_screen">
</div>
【讨论】:
【参考方案11】:要滚动到消息框顶部的特定元素,请查看以下演示:
https://jsfiddle.net/6smajv0t/
function scrollToBottom()
const messages = document.getElementById('messages');
const messagesid = document.getElementById('messagesid');
messages.scrollTop = messagesid.offsetTop - 10;
scrollToBottom();
setInterval(scrollToBottom, 1000);
#messages
height: 200px;
overflow-y: auto;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="messages">
<div class="message">
Hello world1
</div>
<div class="message">
Hello world2
</div>
<div class="message">
Hello world3
</div>
<div class="message">
Hello world4
</div>
<div class="message">
Hello world5
</div>
<div class="message">
Hello world7
</div>
<div class="message">
Hello world8
</div>
<div class="message">
Hello world9
</div>
<div class="message" >
Hello world10
</div>
<div class="message">
Hello world11
</div>
<div class="message">
Hello world12
</div>
<div class="message">
Hello world13
</div>
<div class="message">
Hello world14
</div>
<div class="message">
Hello world15
</div>
<div class="message" id="messagesid">
Hello world16 here
</div>
<div class="message">
Hello world17
</div>
<div class="message">
Hello world18
</div>
<div class="message">
Hello world19
</div>
<div class="message">
Hello world20
</div>
<div class="message">
Hello world21
</div>
<div class="message">
Hello world22
</div>
<div class="message">
Hello world23
</div>
<div class="message">
Hello world24
</div>
<div class="message">
Hello world25
</div>
<div class="message">
Hello world26
</div>
<div class="message">
Hello world27
</div>
<div class="message">
Hello world28
</div>
<div class="message">
Hello world29
</div>
<div class="message">
Hello world30
</div>
</div>
【讨论】:
【参考方案12】:const messages = document.getElementById('messages');
function appendMessage()
const message = document.getElementsByClassName('message')[0];
const newMessage = message.cloneNode(true);
messages.appendChild(newMessage);
function getMessages()
// Prior to getting your messages.
shouldScroll = messages.scrollTop + messages.clientHeight === messages.scrollHeight;
/*
* Get your messages, we'll just simulate it by appending a new one syncronously.
*/
appendMessage();
// After getting your messages.
if (!shouldScroll)
scrollToBottom();
function scrollToBottom()
messages.scrollTop = messages.scrollHeight;
scrollToBottom();
setInterval(getMessages, 100);
#messages
height: 200px;
overflow-y: auto;
<div id="messages">
<div class="message">
Hello world
</div>
</div>
【讨论】:
【参考方案13】:我更喜欢使用 Vanilla JS
let chatWrapper = document.querySelector('#chat-messages');
chatWrapper.scrollTo(0, chatWrapper.offsetHeight );
其中 element.scrollTo(x-coord, y-coord)
【讨论】:
@AdamVýborný Lmao 是的,刚刚注意到。 @AdamVýborný 这不是驳回答案的理由。今天仍然有人遇到同样的问题,也许您在 7 年前找到的解决方案不再被认为是合适的方法。 @GustavoMaximo 我没有拒绝任何事情【参考方案14】:使用这个
function getMessages(letter)
var div = $('#messages');
$.get('msg_show.php', function (data)
div.html(data).animate(scrollTop: div.prop("scrollHeight"));
//use append() if msg_show.php returns single unread msg.
);
setInterval(getMessages, 100);
【讨论】:
以上是关于自动向下滚动聊天 div的主要内容,如果未能解决你的问题,请参考以下文章