WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Баг в Chrome: textarea enter jump

Прыгает скрол textarea. Как смоделировать баг:

  1. Перезагружаем эту страницу.
  2. Прокручиваем немного скрол в textarea.
  3. Ставим курсор, куда-нибудь в середину.
  4. Нажимаем Enter.
  5. Скрол прыгает вниз, и курсор оказывается вверху textarea.

Также прыгает скрол самого окна. Как смоделировать баг:

  1. Перезагружаем эту страницу.
  2. Прокручиваем скрол textarea в конец.
  3. Прокручиваем скрол окна, так чтобы начало textarea выходило за верх окна.
  4. Ставим курсор, куда-нибудь в середину textarea.
  5. Нажимаем Enter.
  6. Скрол 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()
Комментариев нет