Transition de hauteur contournable: animez après l'ajout (shift + enter) et supprimez une ligne de texte

Il fonctionne jusqu'à présent sur l'utilisation de l'attribut contenteditable sur la <div> avec la fonction autogrow d'une zone de texte . Aussi la transition en hauteur de celui-ci . Tout fonctionne bien, à l'exception d'une chose, de supprimer des personnages, d'être spécifique, d'une ligne, ne pas animer sa taille, contrairement à l'ajout de nouvelles lignes. J'ai encore un peu de connaissances sur CSS.

 .autogrow { border: 1px solid rgb( 0, 0, 0 ); padding: 10px; } @keyframes line_insert { from { height: 0px; } to { height: 20px; } } .autogrow[contenteditable] > div { animation-duration: 250ms; animation-name: line_insert; } .autogrow[contenteditable] { overflow: hidden; line-height: 20px; } 
 <div class="autogrow" contenteditable="true"></div> 

Lorsque j'appuie sur Shift + Entrée , elle ne s'anime pas non plus, elle fonctionne bien tout en appuyant sur Entrée . Juste la suppression des lignes et la combinaison de touches Shift + Entrée lors de la saisie d'une nouvelle ligne est le problème.

Comment le faire fonctionner? Est-ce possible d'utiliser un CSS pur? Ou en ajoutant une fonction javascript?

Pour éviter ces problèmes, j'utilise personnellement une solution non basée sur des animations / transitions CSS qui ont toujours eu des problèmes. Par exemple, dans votre implémentation CSS, il existe un effet de rebond en utilisant l' entrée trop rapide (vous pouvez ralentir l'animation pour la voir mieux).

Effet de rebondissement

En outre, la nouvelle gestion des lignes est différente entre les navigateurs, certains ajouteront <div><br></div> , certaines versions d'IE ajoutent uniquement <br> , etc.

Je n'ai jamais réussi à réparer tous ces problèmes ou à trouver une implémentation qui corrige tous ces éléments, alors j'ai décidé de ne pas modifier tout le comportement des contenteditable , de laisser le navigateur faire est une magie qui fonctionne plutôt que de réagir à ce qui se passe.

Nous ne devons même pas nous soucier des événements clés tels que Shift + Enter ou des événements comme la suppression, etc., tous ceux-ci sont gérés de manière native par le navigateur.

Je choisis à la place d'utiliser 2 éléments: l'un pour le contenteditable réelle et l'autre pour le style de mon contenteditable qui sera celui qui a des animations / transitions en hauteur basées sur la hauteur réelle du contenteditable .

Pour ce faire, je surveille tous les événements qui peuvent changer la hauteur d'un contenteditable et si la hauteur de mon élément de style n'est pas la même, j'organise l' élément de coiffage .

 var kAnimationSpeed = 125; var kPadding = 10; $('div[contenteditable]').on('blur keyup paste input', function() { var styleElement = $(this).prev(); var editorHeight = $(this).height(); var styleElementHeight = styleElement.height(); if (editorHeight !== styleElementHeight - kPadding * 2) { styleElement.stop().animate({ height: editorHeight + kPadding * 2 }, kAnimationSpeed); } }); 
 .autogrowWrapper { position: relative; } .autogrow { border: 1px solid rgb(0, 0, 0); height: 40px; /* line-height + 2 * padding */ } div[contenteditable] { outline: none; line-height : 20px; position: absolute; top: 10px; /* padding */ left: 10px; /* padding */ right: 10px; /* padding */ } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="autogrowWrapper"> <div class="autogrow"></div> <div contenteditable="true"></div> </div> 

C'est un peu méchant, mais ça marche.

D'abord, modifiez votre CSS

 .autogrow { border: 1px solid rgb( 0, 0, 0 ); padding: 10px; } @keyframes line_insert { from { height: 0px; } to { height: 20px; } } .autogrow[contenteditable] > div { animation-duration: 250ms; animation-name: line_insert; } .autogrow[contenteditable] { overflow: hidden; line-height: 20px; } 

Ensuite, ajoutez ce jQuery qui détecte Shift + Enter events et ajoute un div chaque fois qu'ils se produisent

 $(".autogrow").keydown(function(e){ if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13) { $(this).animate({height: $(this).height()+20},200); $(this).append('<div><br></div>'); } }); 

Et cela devrait fonctionner.

Vérifiez violon https://jsfiddle.net/wx38rz5L/582/