web-dev-qa-db-fra.com

Faites défiler automatiquement le chat div

J'ai ce code, pour charger le chat

    function getMessages(letter) {
    var div = $("#messages");
    $.get('msg_show.php', function(data) {
        div.html(data);   
    });
}

setInterval(getMessages, 100);

Ce que je dois ajouter pour faire défiler automatiquement #messages div au chargement de la page, et à chaque nouvelle publication de discussion? 

Cela ne fonctionne pas:

    function getMessages(letter) {
    var div = $("#messages");
    $.get('msg_show.php', function(data) {
        div.html(data);
        $('#messages').scrollTop($('#messages')[0].scrollHeight);
    });
}

setInterval(getMessages, 100);
12
Adam Výborný

Passons d'abord en revue quelques concepts utiles concernant le défilement:

  • scrollHeight : taille totale du conteneur.
  • scrollTop : quantité de défilement que l'utilisateur a effectuée.
  • clientHeight : quantité de conteneur qu'un utilisateur voit.

Quand faut-il faire défiler?

  • L'utilisateur a chargé des messages pour la première fois.
  • De nouveaux messages sont arrivés et vous vous trouvez au bas du défilement (vous ne voulez pas forcer le défilement lorsque l'utilisateur fait défiler l'écran pour lire les messages précédents).

Par programme c'est:

if (firstTime) {
  container.scrollTop = container.scrollHeight;
  firstTime = false;
} else if (container.scrollTop + container.clientHeight === container.scrollHeight) {
  container.scrollTop = container.scrollHeight;
}

Simulateur de chat complet (avec 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>

25
zurfyx

C'est difficile à dire sans connaître le code HTML, mais je suppose que votre div n'a pas de hauteur définie et/ou ne permet pas de débordement (par exemple, via CSS height: 200px; overflow: auto).

J'ai créé un échantillon de travail sur jsfiddle: http://jsfiddle.net/hu4zqq4x/

J'ai créé une balise HTML factice dans une div qui est a) débordante et b) a une hauteur définie . Le défilement se fait en appelant la fonction.

function getMessages(letter) {
    var div = $("#messages");
    div.scrollTop(div.prop('scrollHeight'));
}

, dans ce cas, une fois sur 'documentReady'.

prop('scrollHeight') va accéder à la valeur de la propriété sur le premier élément de l'ensemble des éléments correspondants.

8
UweB
    var l = document.getElementsByClassName("chatMessages").length;
    document.getElementsByClassName("chatMessages")[l-1].scrollIntoView();

cela devrait marcher

1
iErcan

après avoir ajouté dans JQuery, ajoutez simplement cette ligne

<script>
    $("#messages").animate({ scrollTop: 20000000 }, "slow");
</script>
1
Govan

Ce que vous devez faire est de le diviser en deux divs. Un avec débordement défini pour faire défiler, et un intérieur pour contenir le texte afin que vous puissiez obtenir sa taille. 

<div id="chatdiv">
    <div id="textdiv"/>
</div>

textdiv.html("");
$.each(chatMessages, function (i, e) {
    textdiv.append("<span>" + e + "</span><br/>");
});
chatdiv.scrollTop(textdiv.outerHeight());

Vous pouvez vérifier un jsfiddle ici: http://jsfiddle.net/xj5c3jcn/1/

Évidemment, vous ne voulez pas reconstruire l'intégralité du texte div à chaque fois, alors prenez cela avec un grain de sel - juste un exemple.

1
aqez

Comme je ne suis pas maître en js mais que j’écris moi-même le code qui vérifie si l’utilisateur est en bas . Si l’utilisateur est en bas, la page de discussion défilera automatiquement avec le nouveau message . défilement automatique vers le bas ..

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

code HTML - 

<div id="chat_con" class="chat_screen">
</div>
0
Gaurav Saini

J'ai découvert cette méthode très simple en expérimentant: définissez scrollTo à la hauteur de la div.

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
0
Cubetastic

si vous faites juste défiler, cela créera un problème lorsque l'utilisateur voudra voir son message précédent. vous devez donc créer quelque chose qui, lorsque le nouveau message vient, n’est que le code. utilisez la dernière version de jquery. 1.ici j'ai vérifié la hauteur avant que le message ne soit chargé . 2. vérifiez à nouveau la nouvelle hauteur . 3. si la hauteur est différente seulement à ce moment-là, il défilera sinon il ne défilera pas . 4. pas dans la condition si vous pouvez mettre toute sonnerie ou toute autre fonctionnalité dont vous avez besoin. cela jouera quand un nouveau message viendra. Merci

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
    }
0

Ne devez pas mélanger jquery et javascript. Utilisez comme ça,

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)

Mettez la méthode scrollTop() à l'intérieur de get().

De plus, vous avez manqué un paramètre dans l'appel à la méthode getMessage.

0
Anoop Joshi

sa travaillé pour moi essayer ceci, laissez-moi savoir si des doutes,

setInterval(function () {
    $("#messages").load("msg_show.php");

   $("#messages").animate({
        scrollTop: $("#messages")[0].scrollHeight}, -500);

}, 1000);
0
Shaik Matheen