Баг скроллинга в чате (на моб.устройстве)

Статус
Закрыто для дальнейших ответов.

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
Доброго времени суток. Помогите найти и устранить ошибку.
При отправке сообщения, чат скроллится в самый конец и через секунду случается скачек на 4-5 сообщения вверх и последние отправленные уже не видно. Не знаю в чем может быть причина. По хорошему, чат должен скроллится в конец к последнему сообщению и на нем фиксироваться.

С ПК вроде все нормально отображается, а вот с мобильного устройства замечаются скачки и смещение сообщений.

Прикладываю видео с багом
https://www.youtube.com/watch?v=ytq17UnTXxM

Исходники чата
https://cloud.mail.ru/public/4j3U/3k3moM4K8
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Запустил скрипт локально. Всё работает.
Старенький Firefox 56 и последний Хром.
В каком браузере ошибка?
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
BaNru сказал(а):
Запустил скрипт локально. Всё работает.
Старенький Firefox 56 и последний Хром.
В каком браузере ошибка?
Это мобильный браузер Safari

Нашел этот чат на GitHub, по функционалу полностью устраивает.
Но вот почему-то на мобильных устройствах происходит скачек сообщений, видимо из-за отсутствия фиксированной высоты блоков сообщений. Но когда ставлю фиксированную например height:50px;, то баг скроллинга пропадает. А когда убираю высоту или ставлю min-height, то все равно случается баг.
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Проверить в Сафари не могу.

Стоит попробовать обновить jQ до актуальной версии.

Ошибка вот в этих строках
Код:
...
var oldscrollHeight = $("#chatbox").attr("scrollHeight") - 20; //Scroll height before the request
...
var newscrollHeight = $("#chatbox").attr("scrollHeight") - 20; //Scroll height after the request
if(newscrollHeight > oldscrollHeight){
   $("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
}
...
Скорее всего в консоли Сафари можно увидеть ошибку и уже дальше можно смотреть на проблему.
Без этого я не смогу подсказать.

Ещё, как вариант, посмотреть Issues на Гибхабе у проекта, либо форки, там где-то есть, посмотреть кто вносил правки в эти строки и попробовать применить у себя.
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
<div class="msgln"> - это обертка каждого сообщения чата.

Одним из решений вижу - это задать через скрипт фиксированную высоту каждого сообщения, исходя из их содержимого.

Например
В одном сбщ 4 строки - скрипт высчитал высоту блока в 70px и задал ее.
В другом сбщ 8 строк - скрипт высчитал высоту блока в 140px и задал ее.
Тогда думаю баг исчезнет.
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
В других браузерах ошибки нет.
Вообще в гугле много про похожее пишут, не только по Сафари.
И даже по этому чату (по крайней мере куску кода похожему)

Если знать точно ошибку, которая пишется в консоли, то можно точнее дать ответ.

Один из вариантов решения заменить везде
Код:
.attr("scrollHeight")
На
Код:
[0].scrollHeight
А вариантов обойти, сделать костыли, много.

PS А обновить JQ всё равно настоятельно рекомендую. Там используется старая и неповоротливая версия. Конечно придётся несколько правок под новую версию внести.
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
BaNru сказал(а):
В других браузерах ошибки нет.
Вообще в гугле много про похожее пишут, не только по Сафари.
И даже по этому чату (по крайней мере куску кода похожему)

Если знать точно ошибку, которая пишется в консоли, то можно точнее дать ответ.

Один из вариантов решения заменить везде

.attr("scrollHeight")
На
Код:
[0].scrollHeight
А вариантов обойти, сделать костыли, много.

PS А обновить JQ всё равно настоятельно рекомендую. Там используется старая и неповоротливая версия. Конечно придётся несколько правок под новую версию внести.
Заменил на [0].scrollHeight и поставил версию https://code.jquery.com/jquery-3.4.1.min.js
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Что-то у меня он не с того, ни с сего сломался.
Вчера работал, а сегодня прокис.

В общем вот тебе рабочий код, исправил и частично улучшил. Проверяй.

<script type="text/javascript"
src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

<script type="text/javascript">
// jQuery Document
function loadLog(){
var oldscrollHeight = $("#chatbox")[0].scrollHeight - 20; //Scroll height before the request
$.ajax({
url: "chatlog.php",
cache: false,
success: function(html){
$("#chatbox").html(html); //Insert chat log into the #chatbox div

//Auto-scroll
var newscrollHeight = $("#chatbox")[0].clientHeight - 20; //Scroll height after the request
if(newscrollHeight < oldscrollHeight){
$("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
}
},
});
}

$(function() {
//If user submits the form
$("#submitmsg").on('click',function(){
var clientmsg = $("#usermsg").val();
if($("#usermsg").val()==""){return false;} // отмена пустого сообщения
$.post("post.php", {text: clientmsg});
$("#usermsg").prop("value", "");
loadLog();
return false;
});
setInterval(loadLog, 2500);
});
</script>

Обрати внимание, у тебя в конце дублировалось подключение JQ, удали дублирование.

Добавлено позже =>

Проверил на мобильном, в общем...выкинул всё из кода и работает (из функции)

function loadLog(){
$.ajax({
url: "chatlog.php",
cache: false,
success: function(html){
$("#chatbox").html(html); //Insert chat log into the #chatbox div
$("#chatbox").animate({ scrollTop: $("#chatbox")[0].scrollHeight - 20 }, 'normal'); //Autoscroll to bottom of div
},
});
}

Или я ночью туплю, или разработчик там сложностей придумал ненужных. У меня везде работает нормально.

Но чтобы чат нормально отображался на мобилах, рекомендую добавить строчку в HEAD и заодно указать кодировку

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
И, соответственно убрать конвертирование в POST
Код:
fwrite($fp, "<div class='msgln'>(".date("g:i A").") <b>".$_SESSION['name']."</b>: ".stripslashes($text)."<br></div>\n");
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
"В общем вот тебе рабочий код, исправил и частично улучшил. Проверяй."

Пока что-то не хочет работать. Страница просто перезагружается.
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
У меня работает. Значит ты что-то сделал не так.

Ещё внёс правку, чтобы сразу после отправки обновлялось, там было неправильно написано
Код:
// jQuery Document
function loadLog(){       
    $.ajax({
        url: "chatlog.php",
        cache: false,
        success: function(html){       
            $("#chatbox").html(html); //Insert chat log into the #chatbox div   
            $("#chatbox").animate({ scrollTop: $("#chatbox")[0].scrollHeight - 20 }, 'normal'); //Autoscroll to bottom of div
          },
    });
}

$(function() {
    //If user submits the form
    $("#submitmsg").on('click',function(){
            var clientmsg = $("#usermsg").val();
            if($("#usermsg").val()==""){return false;} // отмена пустого сообщения
            $.post("post.php", {text: clientmsg})
                .done(loadLog);
            $("#usermsg").prop("value", "");
        return false;
    });
    setInterval(loadLog, 2500);
});
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
Истина где-то рядом. Все работает куда лучше.

Исходники во вложении.

Файл index.php, когда в конце скрипта убираем setInterval(loadLog, 2500); то все ок, но нам как-то нужно обновлять чат на наличие новых сбщ в реальном времени, поэтому setInterval(loadLog, 2500); нужно куда-то впихнуть.

Если ставим setInterval(loadLog, 2500); то сообщения начинают дергаться каждые 2сек. (см.второе видео)

Это только в мобильных версиях браузера.

Значит имеем.

Первое видео без setInterval https://www.youtube.com/watch?v=9nRTesa5bPk

Второе видео с setInterval https://www.youtube.com/watch?v=-rw4XG2EUko
 

Вложения

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Вероятно дергается из-за неверного вычитания PX.
Там есть -20, попробуй поиграться с этой цифрой. Если не поможет, тогда посмотрю дальше.
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
Как раз этим вот и занялся))

BaNru сказал(а):
Вероятно дергается из-за неверного вычитания PX.
Там есть -20, попробуй поиграться с этой цифрой. Если не поможет, тогда посмотрю дальше.
 

Grasss

Active Member
Регистрация
02.11.2017
Сообщения
36
BaNru сказал(а):
Вероятно дергается из-за неверного вычитания PX.
Там есть -20, попробуй поиграться с этой цифрой. Если не поможет, тогда посмотрю дальше.
BaNru сказал(а):
Вероятно дергается из-за неверного вычитания PX.
Там есть -20, попробуй поиграться с этой цифрой. Если не поможет, тогда посмотрю дальше.
Разработчик прислал обновленный скрипт, но там при обновлении страницы отображается только последнее отправленное сообщение, а по идее должны отображаться все сообщения. В принципе, до обновления страницы, список сообщений идет ровно, без дерганий. Файлы во вложении.

Демо чата http://sss.msk0.ru/


----------------------------------------------------------------
Hey guys! I'm the original author of the article. I recently checked
this page out and saw it's still frequented. Even if it just helps one
person, I took a few mins to update the source files to work with jQuery
1.11 (tested on Apache 2.2, PHP 5.3 Fast).
You can download the updated source files over at http://navadev.com/archives/we ...
Fixes (thanks to those that pointed them out):
Everyone: changed opening tags
Chris Maciote: Changed update time to 70ms
Luciano: Fixed Enter key on IE bug using keydown event handler
Liam: Chat now shows "User has entered" message
Vincent: chat now loads clean page when the user enters
Tushar: Scrollbar will now stay up if you've scrolled up to look for a previous msg
mickeljuice: fixed outdated jQuery scroll down
Forest: Log file now only stores 1 line, so the data requested will be small (eg. 160 bytes for 100 chars)
John: thanks for the form/focus tips!
 

Вложения

  • 4 КБ Просмотры: 23
  • 359 байт Просмотры: 23
  • 71 байт Просмотры: 20
  • 71 байт Просмотры: 24

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Версия не лучше, чем была:
1) Интервал обновления 70ms, это фактически DDOS будет твоего сервера. Менее 1000 мс (1 сек) ставить нельзя на такое.
2) В файле POST есть такое

//Clear file
$fp = fopen("log.html", 'w');
fclose($fp);

Комментарий говорит сам за себя. Удаление данных из файла.
3) В index.php идут не обновление фрейма, а добавление. То есть смысл его нового чата в том, что он только лишь добавляет новые сообщения в чат, поэтому была очистка файла. История не хранится.
Чтобы это исправить надо написать (не забыв про второй пункт)
Код:
$("#chatbox").html(html);
 
Статус
Закрыто для дальнейших ответов.
Верх Низ