Автосайз textarea
На этом блоге я пишу текст в обычном textarea
, безо всяких визивигов. Это осознанный выбор. Markdown наше все. Но все же писать в просто textarea не столь удобно. Хочется автосайз и несколько шорткатов: чтобы CTRL+D и Tab работали как в обычных текстовых редакторах. Сейчас про автосайз.
Самое первое нагугленое решение такое
function autosize(e) {
e.target.style.height = '1px';
e.target.style.height = e.target.scrollHeight + 'px';
}
function AutosizeTextArea() {
return <textarea style={{overflowY: 'hidden'}} onInput={autosize}/>;
}
Если вы его запустите, то будете довольны. Работает превосходно.
До поры до времени. Все дело в этом 1px
. Когда текст будет большой, то при уменьшении размера до 1-го пиксела, будет и изменен скрол страницы. При восстановлении размера, будет скрол обратно. Это раздражает.
Кажется тут пригодиться старая добрая техника запоминания скрола.
function autosize(e) {
const scrollTop = window.scrollY;
e.target.style.height = '1px';
e.target.style.height = e.target.scrollHeight + 'px';
window.scrollTo({ top: scrollTop });
}
Все работает прекрасно, но есть нюанс =)
Если у вас включено.
html {
scroll-behavior: smooth;
}
А скорее всего оно у вас включено, то скролл вы все же увидите. Поэтому нужно эту штуку выключать, а потом включать:
function autosize(e) {
document.documentElement.style.scrollBehavior = 'auto';
const scrollTop = window.scrollY;
e.target.style.height = '1px';
e.target.style.height = e.target.scrollHeight + 'px';
window.scrollTo({ top: scrollTop });
document.documentElement.style.scrollBehavior = 'smooth';
}
Все работает превосходно. Как микро оптимизацию, я бы рекомендовал обернуть функцию в тротлер
const autosize = throttle((e) => {
document.documentElement.style.scrollBehavior = 'auto';
const scrollTop = window.scrollY;
e.target.style.height = '1px';
e.target.style.height = e.target.scrollHeight + 'px';
window.scrollTo({ top: scrollTop });
document.documentElement.style.scrollBehavior = 'smooth';
}, 100);
Вот и все. Всем добра!