J'ai corrigé quelques bugs dans la réponse fournie par Reigel (la réponse acceptée):
- L'ordre dans lequel les entités html sont remplacées maintenant ne provoque pas de code inattendu dans l'élément shadow. (L'original a remplacé ">" par "& ampgt;", provoquant un mauvais calcul de la hauteur dans de rares cas)
- Si le texte se termine par une nouvelle ligne, l'ombre reçoit désormais un caractère supplémentaire "#", au lieu d'avoir une hauteur supplémentaire fixe, comme c'est le cas dans l'original.
- Le redimensionnement de la zone de texte après l'initialisation met à jour la largeur de l'ombre.
- word-wrap ajouté: mot de pause pour l'ombre, donc il se brise comme une zone de texte (forçant les pauses pour les mots très longs)
Il reste quelques problèmes concernant les espaces. Je ne vois pas de solution pour les espaces doubles, ils sont affichés sous forme d'espaces simples dans l'ombre (rendu html). Cela ne peut pas être résolu en utilisant & nbsp ;, car les espaces doivent se rompre. En outre, la zone de texte coupe une ligne après un espace, s'il n'y a pas de place pour cet espace, elle coupera la ligne à un point antérieur. Les suggestions sont les bienvenues.
Code corrigé:
(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));