Казалось бы тривиальная задача: поле, которое бы автоматически меняло свою высоту в зависимости от внутреннего текста. Нечто подобное есть в редакторе, в котором я сейчас пишу этот текст 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;
}
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;// для того чтобы строки не переносились
}
Результат
//
этот способ тоже имеет один недостаток. Если строка по ширине больше чем поле, что она не переносится а уходит за его пределы. При этом появляется полоса прокрутки.


Комментарии
не работает ни хрена, вот и не понимай процесс и не ручайся за работу. а ещё лучше не пиши больше