Я исправил несколько ошибок в ответе Рейгеля (принятый ответ):
- Порядок, в котором заменяются html-сущности, теперь не вызывает неожиданного кода в теневом элементе. (В оригинале ">" заменено на "& ampgt;", что в некоторых редких случаях приводило к неправильному вычислению высоты).
- Если текст заканчивается новой строкой, тень теперь получает дополнительный символ «#» вместо фиксированной добавленной высоты, как в оригинале.
- Изменение размера текстовой области после инициализации действительно обновляет ширину тени.
- добавлен перенос слов: break-word для тени, поэтому он разбивается так же, как текстовое поле (принудительные разрывы для очень длинных слов)
Остались некоторые вопросы, касающиеся пробелов. Я не вижу решения для двойных пробелов, они отображаются как одиночные пробелы в тени (рендеринг html). Этого нельзя избежать, используя & nbsp ;, потому что пробелы должны разорваться. Кроме того, текстовое поле разрывает строку после пробела, если для этого места нет места, оно прерывает строку в более ранней точке. Предложения приветствуются.
Исправленный код:
(function ($) {
$.fn.autogrow = function (options) {
var $this, minHeight, lineHeight, shadow, update;
this.filter('textarea').each(function () {
$this = $(this);
minHeight = $this.height();
lineHeight = $this.css('lineHeight');
$this.css('overflow','hidden');
shadow = $('<div></div>').css({
position: 'absolute',
'word-wrap': 'break-word',
top: -10000,
left: -10000,
width: $this.width(),
fontSize: $this.css('fontSize'),
fontFamily: $this.css('fontFamily'),
lineHeight: $this.css('lineHeight'),
resize: 'none'
}).appendTo(document.body);
update = function () {
shadow.css('width', $(this).width());
var val = this.value.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\n/g, '<br/>')
.replace(/\s/g,' ');
if (val.indexOf('<br/>', val.length - 5) !== -1) { val += '#'; }
shadow.html(val);
$(this).css('height', Math.max(shadow.height(), minHeight));
};
$this.change(update).keyup(update).keydown(update);
update.apply(this);
});
return this;
};
}(jQuery));