Bonjour,
Je voudrais faire un textarea qui s'adapte au texte par exemple pour l'administration pour éditer un article ou autre, le textarea devra avoir une taille en fonction du contenu qu'il y a dedans.
Mon script actuel fonctionne quand le textarea est vide, il s'agrandit ou diminue automatiquement.
Mais quand le textarea est déjà pré-rempli, par exemple pour éditer un article le texte provient de la base de données, il ne prend pas la bonne taille de suite.
Voici mon script :
jQuery.each(jQuery('textarea[data-autoresize]'), function() {
var offset = this.offsetHeight - this.clientHeight;
var resizeTextarea = function(e) {
jQuery(e).css('height', 'auto').css('height', e.scrollHeight + offset);
};
jQuery(this).on('keyup input', function() { resizeTextarea(this); }).removeAttr('data-autoresize');
resizeTextarea(this);
});
Ce que je ne comprend c'est quand je tape une touche dans mon textarea la fonction marche correctement le textarea va bien s'adapter au contenu, mais au chargement de la page : la fonction scrollHeight
me donne pas la bonne dimension, je ne sais pas comment faire pour y remédier.
Bonjour.
Il y a plusieurs choses qui me dérangent dans ton code.
La première, c'est pourquoi tu utilises autant de fois jQuery
, alors que si tu veux simplement éviter les éventuels conflits avec $
, il te suffit d'entourer ton code de cette manière par exemple :
jQuery(function($) {
/* Puis le code avec $, exemple :
$('textarea[data-autoresize]', function() {
...
});
*/
});
Ensuite, tu donnes deux valeurs successivement pour l'attribut height
(auto et e.scrollHeight + offset).
Pour terminer, tu supprimes l'attribut data-autoresize
, alors que juste après tu veux manipuler l'élément, je vois assez mal comment il pourra sélectionner ton élément si tu as déja supprimé le sélecteur qui lui permettait de l'identifier.
C'est un script que j'ai pris sur internet après modification du code, le voici :
(function($) {
$.each($('textarea[data-autoresize]'), function() {
var offset = this.offsetHeight - this.clientHeight;
var resizeTextarea = function(e) {
$(e).css('height', 'auto').css('height', e.scrollHeight + offset);
};
$(this).on('keyup input', function() { resizeTextarea(this); });
resizeTextarea(this);
});
})(jQuery);
Après cela ne m'explique pas pourquoi la fonction scrollHeight
me donne pas la bonne valeur au démarrage de la page et quand je tape n'importe quel touche dans le textarea la fonction donne la bonne valeur.
Après test le premier $(e).css('height', 'auto')
, si je ne mets pas cela les lignes inutiles ne sont pas supprimées
Le CSS du textarea si cela est nécessaire :
textarea {
width: 100%;
padding: 15px;
font-size: 16px;
font-family: "Roboto";
line-height: 1.5;
resize: none;
box-sizing: border-box;
word-wrap: break-word;
}
Tu peux utiliser ce plugin et exécuter un trigger de l'événement "autosize:update" dès que le dom est prêt comme ça ça donnera la bonne hauteur à ton textarea.
Après ce qui m'embête avec le plugin c'est que le fichier est assez lourd par rapport à mon fichier qui fait 6 lignes qui marche bien sauf au démarrage de la page
J'ai réussi à la faire fonctionner mais il fait exactement la même chose que mon script :
var ta = document.querySelector('textarea');
autosize(ta);
var evt = document.createEvent('Event');
evt.initEvent('autosize:update', true, false);
ta.dispatchEvent(evt);
En remplissant le textarea avec des lorem ipsum il me redimensionne mon textarea (height : 230px) au lieu de (height : 260px) qui est la taille idéale
Il a le même comportement que mon script, ce qui est bizarre.
Donc ce que je voudrais savoir c'est pourquoi la fonction scrollHeight
à ce comportement bizarre
Si quelqu'un pourrait me dire pourquoi la fonction scrollHeight
n'a pas le même comportement en l'appelant en direct que dans un on keyup
Voici mon script actuel :
(function($) {
$.each($("textarea[data-autoresize]"), function() {
var offset = this.offsetHeight - this.clientHeight;
var resizeTextarea = function(e) {
$(e).css("height", "auto").css("height", e.scrollHeight + offset);
};
$(this).on("keyup input", function() { resizeTextarea(this); });
if ($(this).height() < this.scrollHeight + offset) {
resizeTextarea(this);
}
});
})(jQuery);
YOP.
Mon script actuel fonctionne quand le textarea est vide, il s'agrandit ou diminue automatiquement.
Mais quand le textarea est déjà pré-rempli, par exemple pour éditer un article le texte provient de la base de données, il ne prend pas la bonne taille de suite.
Ce qui est normal puisque tu appelles la fonction resizeTextarea
que pour les événements keyup et input. (et non directement)
$.each($('textarea[data-autoresize]'), function() {
var offset = this.offsetHeight - this.clientHeight;
var resizeTextarea = function(el) {
$(el).css('height', 'auto').css('height', el.scrollHeight + offset);
};
resizeTextarea(this);
$(this).on('keyup input', function() {
resizeTextarea(this);
}).removeAttr('data-autoresize');
});
Non si tu regarde bien mon dernier message je vérifie au démarrage si la taille de mon textarea est inférieur à la fonction scrollHeight() et du coup je le redimensionne
if ($(this).height() < this.scrollHeight + offset) {
resizeTextarea(this);
}
Ton fiddle ne marche pas en augmentant le texte ^^ comme le mien avec peu de texte il marche mais avec une quantité plus grande il ne suit plus
Avec des bordures le scroll apparaît aussi mais cela est facilement modifiable je pense
J'ai fait une petite modification de ton code mais quand on tape une touche dans le textarea il s'agrandit beaucoup comportement bizarre ^^
Voici le lien : https://jsfiddle.net/43L343aq/5/
Mais au démarrage la dimension est bonne
Tu veux que ta textarea ne dépasse pas la hauteur du contenu visible de la fenêtre?
Si oui: ?
var resizeTextarea = function(el) {
var posy = el.scrollHeight + offset
if (posy > window.innerHeight) {
posy = window.innerHeight/* - 20 a adapter ? */
}
$(el).css('height', 'auto').css('height', posy);
};
Oui je crois si je te comprend bien je veux que le textarea quand je tape des touches dedans qu'il s’adapte toujours au contenu comme au lancement de la page, tu peux m'éditer ton fiddle pour voir les modifications ?
J'ai pris le 2ème code que tu as posté ici, tuas juste à remplacer ta fonction resizeTextarea
par celle que j'ai mise sur mon ancien post. ^^
Ha non on s'est mal compris ce n'est pas ça que je voulais au démarrage ton script fait bien le taff mais c'est quand on écrit quelque chose dans le textarea il agrandit le textarea beaucoup plus qu'il ne le doit ^^
Au démarrage, sa donne cela :
En ajoutant juste un espace dans le textarea, cela donne sa :
Il fait direct des sauts de ligne inutiles
Et plus il y a de lignes dans le textarea plus les sauts de lignes sont importants
Dans mon script j'ai fait sa pour y remédier :
$(e).css("height", "auto").css("height", e.scrollHeight + offset);
Mais dans ton script cela ne fonctionne pas
J'ai réussi à supprimer les lignes inutiles mais quand on fait un saut de ligne le texte fait un décalage à chaque fois, c'est très embêtant.
fiddle
Comment y remédier ?
Ce qui est bizarre aussi c'est que à l'affichage du textarea il ne se redimensionne pas comme il faut avec la police "Roboto" alors qu'avec la police par default de Google Chrome ou "Open Sans" le textarea est bien redimensionner, bizarre.
C'est bizarre car je charge le javascript en dernier et j'attend que le contenu soit charger comment remédier à cela ?
Ha oui mais cela nécessite du code JS en + et d'intégrer les fonts sur le serveur au lieu de les appeller depuis les serveurs de Google qui est bien plus rapide.
Enfaites le problème vient de là depuis le début, car j'ai essayer avec mon premier script avec la police "Open Sans" ou celle de Google Chrome par default et cela marche à la perfection.
Je crois que je vais mettre mes textarea en police "Open Sans" à moins que quelqu'un est une idée pour mettre n'importe quel police depuis Google Fonts sans ajouter du JS supplémentaire
Merci à tous ceux qui m'ont apporté des réponses et votre réactivité.
Si quelqu'un à une solution pour redimensionner un textarea automatiquement avec n'importe quelle police sans ajouter de JavaScript supplémentaire je suis preneur