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