JeuWeb - Crée ton jeu par navigateur
Problème de positionnement de scrollbar (chatbox) - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Problème de positionnement de scrollbar (chatbox) (/showthread.php?tid=7256)



Problème de positionnement de scrollbar (chatbox) - Lindis - 22-11-2014

Bonsoir à la communauté de JeuWeb !

Je viens vers vous afin que vous m'aidiez à régler un problème de taille concernant la scrollbar sur un projet que nous vous présenterons sous peux sur JeuWeb.
(notre projet étant encore peux abouti il est donc inutile à nos yeux d'en faire la promotion pour ne quasiment rien avoir à vous montrer de la partie jeu bien que nous y travaillons d'arrache-pied).

Pourquoi nous ? Parce que depuis un certain temps moi même ayant commencé www.green-paradis.fr et Renaud qui avait son projet www.mon-termite.fr en cours de conception les avons laissé tomber pour nous associer et partir sur un tout nouveau concept qui n'est encore connu des jeux en ligne (oui vous l'aurez bien compris un tout nouveau concept).

Nous rencontrons un soucis au niveau de la scrollbar qui est fixe dans le bas du chat mais si nous voulons voir les quelques messages précédents un peux plus haut à chaque actualisation le Javascript l'emporte et nous remet dans le bas même si on reste cliqué sur la partie défilante de la barre scrollable.

De plus lors de l'envoi d'un message sur la chatbox il faut un millième de seconde pour voir la barre se placer dans le bas pour nous afficher les derniers messages ce qui nous laisse voir cette scrollbar en haut du chat un court instant avant d'aller se coller dans le bas (ça ne fait pas très pro bien que ça ne soit pas super gênant).

Un autre petit problème qui me tracasse moi en particulier c'est un léger blanc pendant l'actu au moment de soumettre le message (une seconde ou les messages contenus dans la table n'apparaissent pas directement).

[Image: 134067chat1.png]
[Image: 150242chat2.png]

Ce problème de scrollbar est présent que quand plusieurs messages apparaissent sur plusieurs lignes sinon celle ci n'est pas visible.

Je dépose ci-dessous le code javascript qui sert au refresh et aussi à fixer la scrollbar dans le bas et je précise que je ne suis pas très calé en Js (déjà des heures de recherche pour trouver d'où peut provenir cette anomalie et très peux de topics sur le web traitent ce sujet et encore moins de topics passés résolus).

Mon amis Renaud et moi comptons beaucoup sur votre aide de ce côté même si nous sommes assez débrouillards au point de ne pas aimer demander aux autres personnes de nous faire le travail (entre autre demander de l'aide).

Cette portion de code Javascript se trouve sur l'index de notre chat qui comprend un div nommé messages_chatbox.


function refresh()
{
var xhr_object = null;
if(window.XMLHttpRequest)
{ // Firefox
xhr_object = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{ // Internet Explorer
xhr_object = new ActiveXObject('Microsoft.XMLHTTP');
}
var method = 'GET';
var filename = 'messages_chatbox.php';
xhr_object.open(method, filename, true);
xhr_object.onreadystatechange = function()
{
if(xhr_object.readyState == 4)
{
var tmp = xhr_object.responseText;

document.getElementById('messages_chatbox').innerHTML = tmp;
}
}
xhr_object.send(null);
element = document.getElementById('messages_chatbox');
element.scrollTop = element.scrollHeight;
setTimeout('refresh()', 1000);
}

Nous vous remercions beaucoup pour l'intérêt que vous nous portez à avoir lu ce post et sachez qu'un service en vaut un autre c'est à charge de revanche.

Dans l'attente de vos réponses passez une bonne soirée.[/b]


RE: Problème de positionnement de scrollbar (chatbox) - Xenos - 22-11-2014

Yop,

Je ne connais pas les technos en question, mais je sais qu'il en existe de plus adaptées que qu'un GET AJAX toutes les secondes.
Perso, n'ayant pas voulu mettre en place de websocket/node ou autre event-driven lorsque j'ai eu besoin d'un petit chat en "temps réel", j'ai utilisé une astuce un peu plus légère: une requête HEAD en AJAX pour savoir si de nouveaux messages sont arrivées et une requête GET lancée uniquement si des messages sont effectivement arrivés. Un petit système de cache coté serveur pour ne pas consulter la BDD lors de la réception du premier AJAX/HEAD, et on arrive à quelque chose de relativement robuste capable de tenir un chat temps réel entre une bonne dizaine de personnes (testé et éprouvé avec des américains, anglais, allemands et français sur le chat).

Pour régler le soucis de scroll, je dirai qu'il faut ramener l’ascenseur en bas que si celui-ci était en bas avant l'actualisation:


function refresh()
{
// note: je ne suis pas certain de cette ligne
var scrollEnBas = (element.scrollTop == element.scrollHeight); // l'ascenseur est-il déjà en bas?
...
element = document.getElementById('messages_chatbox');
if (scrollEnBas)
element.scrollTop = element.scrollHeight;
...
}


L'autre solution, plus élégante mais plus longue à mettre en place, serait de ne pas écraser le contenu du chat, mais bien d'ajouter uniquement les nouveaux messages:


var lastTimestamp = new Date().getTime(); // Date du chat actuellement affiché
function refresh()
{
var xhr_object = null;
if(window.XMLHttpRequest)
xhr_object = new XMLHttpRequest();
else if(window.ActiveXObject)
xhr_object = new ActiveXObject('Microsoft.XMLHTTP');

// Note: ici, xhr_object peut valoir "null": il manque un "else { alert('pas de XHR'); }"

var method = 'GET';
var filename = 'chatbox/messages?format=json&depuis='+lastTimestamp;
xhr_object.open(method, filename, true);
xhr_object.onreadystatechange = function()
{
if(xhr_object.readyState == 4)
{
var tmp = xhr_object.responseText;
var newMessages = ...;
// A construire soi-même
// Conseil: récupérer une réponse JSON et construire les noeuds via JSON.parse()
document.getElementById('messages_chatbox').appendChild(newMessages);
}
}
xhr_object.send(null);
lastTimestamp = new Date().getTime();
setTimeout('refresh()', 1000);
}

Mais cela requiert un peu plus de code, puisqu'il faut:
• Demander au serveur de renvoyer la liste des nouveaux messages depuis une date donnée
• Récupérer cette réponse et construire les éléments du DOM correspondant à ces nouveaux messages (réponse en JSON conseillée)
• On peut aussi éviter la variable globale (c'est préférable) par "encapsulation"

Dans ce second code, le comportement du navigateur dictera le comportement de la barre de scroll (donc, ce ne sera pas un "comportement forcé par le site"). A tester donc, pour voir le comportement final pour l'utilisateur.


Attention aussi car le setTimeout() me semble mal placé.
Ici, on crée l'objet XHR, puis on lance la requête (AJAX: Asynchronous), et sans en attendre la réponse, on lance le setTimeout().
Résultat: si la réponse met plus de 1 seconde pour arriver, le setTimeout se lancera avant que cette réponse ne soit traitée: il lancera une nouvelle requête AJAX.
On risque donc l'engorgement du client.
Une bonne façon de tester la chose est de mettre un "sleep" (de durée aléatoire) pour allonger la durée de la réponse du serveur.

Solution possible:
placer le setTimeout dans la fonction "onreadystatechange" pour ne le lancer qu'une fois la requête reçue et traitée (avec succès ou erreur).


RE: Problème de positionnement de scrollbar (chatbox) - Lindis - 22-11-2014

Merci beaucoup Xenos je vais voir ce que je peux faire avec tout ça.
Et si je galère je demanderais à mon collègue et amis.

En tout cas on vous tiendra informé des suites.

Passe une excellente soirée et merci encore.

Bye.