Автосайз textarea
На этом блоге я пишу текст в обычном textarea
, безо всяких визивигов. Это осознанный выбор. Markdown наше все. Но все же писать в просто textarea не столь удобно. Хочется автосайз и несколько шорткатов: чтобы CTRL+D и Tab работали как в обычных текстовых редакторах. Сейчас про автосайз.
Самое первое нагугленое решение такое
Copyfunction 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-го пиксела, будет и изменен скрол страницы. При восстановлении размера, будет скрол обратно. Это раздражает.
Кажется тут пригодиться старая добрая техника запоминания скрола.
Copyfunction autosize(e) { const scrollTop = window.scrollY; e.target.style.height = '1px'; e.target.style.height = e.target.scrollHeight + 'px'; window.scrollTo({ top: scrollTop }); }
Все работает прекрасно, но есть нюанс =)
Если у вас включено.
Copyhtml { scroll-behavior: smooth; }
А скорее всего оно у вас включено, то скролл вы все же увидите. Поэтому нужно эту штуку выключать, а потом включать:
Copyfunction 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'; }
Все работает превосходно. Как микро оптимизацию, я бы рекомендовал обернуть функцию в тротлер
Copyconst 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);
Вот и все. Всем добра!