Баг в Chrome: textarea enter jump
Прыгает скрол textarea. Как смоделировать баг:
- Перезагружаем эту страницу.
- Прокручиваем немного скрол в textarea.
- Ставим курсор, куда-нибудь в середину.
- Нажимаем Enter.
- Скрол прыгает вниз, и курсор оказывается вверху textarea.
Также прыгает скрол самого окна. Как смоделировать баг:
- Перезагружаем эту страницу.
- Прокручиваем скрол textarea в конец.
- Прокручиваем скрол окна, так чтобы начало textarea выходило за верх окна.
- Ставим курсор, куда-нибудь в середину textarea.
- Нажимаем Enter.
- Скрол textarea уже не прыгает (потому что он уже внизу), но зато теперь прыгает скрол окна.
Версия Хрома в которой проверял последний раз: 84.0.4147.135
Чтобы оградиться от всевозможных скриптов, которые могут быть на этом сайте, скачайте архив ниже там обычный HTML файл, в котором нет ничего кроме такого же (как ниже) поля textarea. Баг также наблюдается, если открыть файл в Хроме.
Как исправить?
Чтобы поправить этот баг, я написал такой скриптик, который возвращает позицию скрола после «прыжка». Скрипт можно вызывать в любое время в любом месте HTML/JS.
/** * Исправляет баг в Хроме, при котором после нажатия на Enter иногда скрол * прыгает вниз и курсор оказывает вверху textarea, хотя был, например, в центре. * * @author Kama * @version 2.2 */ let chrome_bugfix__init = function(){ // not Chrome if( ! ( /Chrome/.test( navigator.userAgent ) && /Google Inc/.test( navigator.vendor ) ) ) return document.addEventListener( 'keydown', function( ev ){ // not textarea, not enter, has `enter_bugfix_off` data attr if( 0 || ev.target.nodeName !== 'TEXTAREA' || ev.key !== 'Enter' || ev.target.dataset.enter_bugfix_off ) return let tx = ev.target let prevScrollTop = tx.scrollTop let prevWinScrollTop = window.scrollY setTimeout( function(){ if( tx.scrollTop - prevScrollTop > 30 ){ tx.scrollTop = prevScrollTop console.log( 'textarea.scrollTop was returned after jump' ) } // window scroll jump too, when textarea scroll at the bottom if( window.scrollY !== prevWinScrollTop ){ window.scrollTo( 0, prevWinScrollTop ) console.log( 'window scrollY was returned after jump' ) } }, 0 ) } ) } chrome_bugfix__init()