Автосайз textarea​Казалось бы тривиальная задача: поле, которое бы автоматически меняло свою высоту в зависимости от внутреннего текста. Нечто подобное есть в редакторе, в котором я сейчас пишу этот текст ckeditor. Называется оно здесь autogrow и реализуется отдельным плагином. 

Да, разумеется и для нативных инпутов есть множество jQuery плагинов, которые выполняют возложенную на них функцию. 

Так сложилось, что мой блог - это не набор простых решений, типа берете такой плагин, подключаете и у Вас все работает. Нет. Я из тех людей, которых результаты запроса в гугле: "Как объединить два массива в, вызывают по меньшей мере негодование. 

Плеяда статей и вопросов на stackoverflow, с ответом: $.extend

У большинства сегодняшних web-developerov, нет ни тени сомнения, что jQuery подключен к любому проекту.

Я не из таких программистов. Есть такие области, в которых нет и не будет jQuery. К примеру, написание плагинов на другие библиотеки или программы. К примеру плагин на ckeditor, допускает использование лишь API самого редактора, потому, как само оно вести порядка 0.5Mb и библиотека в 0.09Mb будет излишней нагрузкой.

В таких ситуациях есть два пути: первый, написать все на API библиотеки, и второй сделать все на vanila.js 

При втором варианте, наш код будет легко портировать на любую другую библиотеку. Все заработает даже вовсе без нее.

Собственно ради чего это отступление - не стоит использовать плагин там, где все и так пишется в несколько строк кода.

Теперь к делу

Все готовые плагины, которые я встретил изучая этот вопрос, работают по одному принципу: создают div элемент, делают все его стили, размеры, шрифты и отступы идентичными textarea. Затем, прячут его, при этом делают это не при помощи display:none а с помощью visibility:hidden

Отличает одно от другого то, что у  display:none нельзя выяснить размер. А у visibility:hidden можно. Чтобы он не мешался, ему делают position:absolute; 

Потом на textarea вешается обработчик keyup,mouseup и change, который синхронизируется содержимое textarea и нашего div'а. Затем, в обратную сторону синхронизируется размер textarea с размером div'a. 

HTML

<div id="dummy"></div>
<textarea id="editor"></textarea>

CSS

#dummy{
 visibility:hidden;
 font-size:14px;
 line-height:14px;
 position:absolute;
 white-space: pre;
 word-break: break-all;
 padding:5px;
}
textarea{
 font-size:14px;
 line-height:14px;
 padding:5px;
}

JavaScript

var editor = document.getElementById('editor'),
      dummy = document.getElementById('dummy')
editor.addEventListener('keyup',function(){
   dummy.innerText = this.value;
   dummy.style.width = this.offsetWidth+'px';
   this.style.height = dummy.offsetHeight+'px';
},false)

Результат

 

//

Так работают эти плагины. Писал код прямо тут, поэтому за работоспособность не ручаюсь. Но я и не претендую, важно понимать сам процесс. Этот способ самый действенный, и рабочий из предложенных мной. 

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

Однако он очевидно «грязный», лишний элемент на странице, к тому же стили поля и блока не так уж и просто синхронизировать в реальном проекте.

 

Есть еще два способа. Первый: каждый раз, при редактировании поля, смотреть его scrollHeight и увеличивать его размер на эту длину.

var editor = document.getElementById('editor');
editor.addEventListener('keyup',function(){
   this.style.height = this.scrollHeight+this.offsetHeight+'px';
},false)

Результат

 

// 0) this.style.height = (this.clientHeight+olh)+'px'; },false) // ]]>

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

 

И наконец самое просто решение. Разбивать содержимое поля по /n/r и умножать на высоту строки. Полученную величину присваивать высоте поля. 

var editor = document.getElementById('editor');
editor.addEventListener('keyup',function(){
   this.style.height = parseInt(this.value.split(/[\n\r]/))*14+'px';
},false)

и css 

teaxtarea{
line-height:14px;
font-size:14px;
white-space: nowrap;// для того чтобы строки не переносились
}

Результат

 

//

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

Рассказать друзьям
author.jpg

Платная консультация по вопросам 1500 руб/час

Прочитали статью и остались вопросы? Меня зовут Валерий и я её автор. С радостью объясню Вам в скайпе все затруднительные моменты, которые остались за рамками статьи!

Подробнее ...

Добавить комментарий


Комментарии   

ывв
+3 # ывв 25.01.2018 13:49
Писал код прямо тут, поэтому за работоспособность не ручаюсь. Но я и не претендую, важно понимать сам процесс. Этот способ самый действенный, и рабочий из предложенных мной.

не работает ни хрена, вот и не понимай процесс и не ручайся за работу. а ещё лучше не пиши больше
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Wilma
0 # Wilma 28.12.2018 16:49
The user dⲟes not want to wasste timе giving information that isn't
necessаry. If you оversell,you're seyting high expectations fоr clients.

Profeѕsionalizeԁ experts and members of friendship helkps ɑt every step and
providing creative and effective solutions to build yourr
site online.

Also vіsit my site: Cannabis SEO Longview Texas (Wilma)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору