Reputation: 731
I have this code, to load chat
function getMessages(letter) {
var div = $('#messages');
$.get('msg_show.php', function (data) {
div.html(data);
});
}
setInterval(getMessages, 100);
What I have to add, to automatically scroll down #messages
div on page load, and again with every new chat post?
This doesn't work:
function getMessages(letter) {
var div = $('#messages');
$.get('msg_show.php', function (data) {
div.html(data);
$('#messages').scrollTop($('#messages')[0].scrollHeight);
});
}
setInterval(getMessages, 100);
Upvotes: 45
Views: 163472
Reputation: 1
You can resolve easily using only css.
.chat-messages { display: flex; flex-direction: column-reverse; }
Now u need to reverse the chat order and works.
Try, See this gits
Upvotes: 0
Reputation: 2143
You can do this with CSS using overflow-anchor
: https://caniuse.com/css-overflow-anchor
const scroller = document.getElementById('scroller')
const anchor = document.getElementById('anchor')
let i = 0;
setInterval(() => {
const p = document.createElement("p")
p.textContent = `Message ${i++}`
scroller.insertBefore(p, anchor)
}, 1000)
#scroller {
/* begin example styling */
display: flex;
flex-direction: column;
align-items: flex-start;
/* end example styling */
}
#scroller * {
/* don't allow the children of the scrollable element to be selected as an anchor node */
overflow-anchor: none;
}
#anchor {
/* allow the final child to be selected as an anchor node */
overflow-anchor: auto;
/* anchor nodes are required to have non-zero area */
height: 1px;
/* begin example styling */
align-self: stretch;
/* end example styling */
}
<div id="scroller">
<!-- append content here -->
<div id="anchor"></div>
</div>
Note that to activate this, the user must first scroll to the bottom of the page. You can work around this by using javascript to trigger an initial scroll as soon as it is possible.
Upvotes: -1
Reputation: 450
Supports new messages and sets scrolling down automatically is similar to Twitch chat
function Chat() {
const [messages, setMessages] = useState<string[]>([])
const container = useRef<HTMLDivElement>(null)
const autoScroll = () => {
const { offsetHeight, scrollHeight, scrollTop } = container.current as HTMLDivElement
if (scrollHeight <= scrollTop + offsetHeight + 100) {
container.current?.scrollTo(0, scrollHeight)
}
}
useEffect(() => {
autoScroll()
}, [messages])
return (
<div ref={container}>
// messages
</div>
)
}
Upvotes: 0
Reputation: 11
Simple solution:
1 - Place in the bottom of your message (Inside)
<a href="#" class="d-none" id="focus-bottom"></a>
2 - When new message is received:
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);
Upvotes: 1
Reputation: 1
Use This
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);
Upvotes: 0
Reputation: 2023
I prefer to use Vanilla JS
let chatWrapper = document.querySelector('#chat-messages');
chatWrapper.scrollTo(0, chatWrapper.offsetHeight );
where element.scrollTo(x-coord, y-coord)
Upvotes: 0
Reputation: 11
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>
Upvotes: 1
Reputation: 21
to scroll till particular element from the message box top checkout the following demo:
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>
Upvotes: 2
Reputation: 32757
Let's review a few useful concepts about scrolling first:
When should you scroll?
Programmatically that is:
if (firstTime) {
container.scrollTop = container.scrollHeight;
firstTime = false;
} else if (container.scrollTop + container.clientHeight === container.scrollHeight) {
container.scrollTop = container.scrollHeight;
}
Full chat simulator (with 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>
Upvotes: 69
Reputation: 21
As I am not master in js but I myself write code which check if user is at bottom. If user is at bottom then chat page will automatically scroll with new message. and if user scroll up then page will not auto scroll to bottom..
JS code -
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 code -
<div id="chat_con" class="chat_screen">
</div>
Upvotes: 0
Reputation: 31
if you just scrollheight it will make a problem when user will want to see his previous message. so you need to make something that when new message come only then the code. use jquery latest version. 1.here I checked the height before message loaded. 2. again check the new height. 3. if the height is different only that time it will scroll otherwise it will not scroll. 4. not in the if condition you can put any ringtone or any other feature that you need. that will play when new message will come. thanks
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
}
Upvotes: 2
Reputation: 1379
after append in JQuery,just add this line
<script>
$("#messages").animate({ scrollTop: 20000000 }, "slow");
</script>
Upvotes: 9
Reputation:
var l = document.getElementsByClassName("chatMessages").length;
document.getElementsByClassName("chatMessages")[l-1].scrollIntoView();
this should work
Upvotes: 0
Reputation: 489
I found out this very simple method while experimenting: set the scrollTo
to the height of the div.
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
Upvotes: 1
Reputation: 315
What you need to do is divide it into two divs. One with overflow set to scroll, and an inner one to hold the text so you can get it's outersize.
<div id="chatdiv">
<div id="textdiv"/>
</div>
textdiv.html("");
$.each(chatMessages, function (i, e) {
textdiv.append("<span>" + e + "</span><br/>");
});
chatdiv.scrollTop(textdiv.outerHeight());
You can check out a jsfiddle here: http://jsfiddle.net/xj5c3jcn/1/
Obviously you don't want to rebuild the whole text div each time, so take that with a grain of salt - just an example.
Upvotes: 1
Reputation: 4110
It's hard to tell without knowing the HTML code, but I'd assume your div doesn't have a height set and/or doesn't allow overflow (e.g. through CSS height: 200px; overflow: auto
).
I've made a working sample on jsfiddle: http://jsfiddle.net/hu4zqq4x/
I created some dummy HTML markup inside a div that is a) overflowing and b) has a set height. Scrolling is done through calling the function
function getMessages(letter) {
var div = $("#messages");
div.scrollTop(div.prop('scrollHeight'));
}
, in this case once on 'documentReady'.
prop('scrollHeight')
will access the value of the property on the first element in the set of matched elements.
Upvotes: 15
Reputation: 25527
Dont have to mix jquery and javascript. Use like this,
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)
Put the scrollTop()
inside get()
method.
Also you missed a parameter in the getMessage
method call..
Upvotes: 0