Создавая редактор постов в админ-панели этого сайта (кстати, редактор получился самый лучший и удобный в мире, ни у кого такого больше нет; о нём будет отдельный пост), столкнулся с задачей по подгонке размера текстовых полей (input и textarea) по размеру контента внутри них. Поле textarea нужно изменять в высоту по количеству строк в нём — пригодится как в редакторе текста, так и в редакторе кода; input мне пришлось менять по ширине текста в редакторе тегов.
О том, какие решения были найдены — под катом.
Сначала я начал решать проблему с textarea. В голову пришла очевиднейшая мысль — подсчитывать количество переносов строк (символ \n) и умножать на значение css-свойства line-height. Довольный, начал печатать длинную строку текста и понял ошибку.
Найденное решение оказалось не таким уж и сложным.
$('textarea').on('keyup change drop paste focusin focusout',function(){
$(this)
.attr('rows','1')
.css('height','auto')
.css('height',$(this)[0].scrollHeight+'px');
});
Всё просто — отдаём расчёт высоты браузеру (height:auto), измеряем высоту контента (свойство scrollHeight берём у DOM-элемента, а не у элемента jQuery) и устанавливаем её как высоту всего текстового поля.
Да, сначала мы указываем, что строка в textarea якобы одна. Дело в том, что если css-свойство height указывет высоту меньшую, чем указывает атрибут rows, то height игнорируется. По умолчанию браузеры обычно устанавливают rows=2, поэтому при наличии даже одной строки текста textarea будет высотой с две строки.
Такое же несложное решение и у подcчёта ширины input.
$('input').on('keyup change drop paste focusin focusout',function(){
var el=$('<span>');
el.html(
$(this).val()
.replace(/ /g,' ')
).insertAfter($(this));
$(this).width(el.width()+1);
el.remove();
});
Демо на jsFiddle. (Более плавное демо с использованием setInterval).
Тут мы создаём элемент span рядом с input и вставляем туда значение из input. Обратите внимание, что padding, margin и размер шрифта у input и span должны быть одинаковы!
Важный момент: к ширине надо прибавить один пиксель, чтобы при пустом input его ширина не становилась равной нулю — тогда элемент пропадёт, и печатать в нём станет невозможно.
Ещё один важный момент — если в input несколько пробелов подряд будут отображаться, то в span они сократятся до одного, и ширина возвратится неверная. Поэтому необходимо заменить все пробелы на , которые не сокращаются браузером.