Entrée unique en ligne contentement

Pour une application que nous développons dans l'entreprise où je travaille, nous avons besoin d'une entrée qui supporte l'insertion d'émoticônes dans notre application Web JS. Nous utilisons actuellement une entrée avec les codes courts de l'émoticône (c.-à-d.: «)» Et souhaitons passer à l'insertion d'images graphiques réelles.

Notre plan d'origine était d'utiliser un <div> contenteditable . Nous utilisons les auditeurs pour l'événement coller ainsi que les différentes interactions clés / souris pour éviter tout marquage indésirable entrant dans le contentement (nous supprimons le texte de ses étiquettes de conteneur et ne laissons que les balises d'image que nous avons insérées).

Cependant, le problème en ce moment est que le div redimensionne si vous mettez suffisamment de contenu (c'est-à-dire que sa hauteur augmente). Nous ne voulons pas que cela se produise, et il n'est pas acceptable que le texte soit caché (c.-à-d. Un overflow: hidden simple overflow: hidden ). Alors:

Existe-t-il un moyen de faire en sorte que le div contentatif se comporte comme une entrée en une seule ligne?

Je voudrais mieux si il y a une propriété d'attributs / css relativement simple que j'ai manqué qui fera ce que je veux, mais si nécessaire, les suggestions de CSS + JS seront également appréciées.

 <style> [contenteditable="true"].single-line { white-space: nowrap; width:200px; overflow: hidden; } [contenteditable="true"].single-line br { display:none; } [contenteditable="true"].single-line * { display:inline; white-space:nowrap; } </style> <div contenteditable="true" class="single-line"> This should works </div>​ 

Je pense que vous recherchez une div contenteditable avec une seule ligne de texte qui défile horizontalement lorsqu'elle déborde la div . Cela devrait faire l'affaire: http://jsfiddle.net/F6C9T/1

HTML:

 <div contenteditable> Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. </div> 

CSS:

 div{ font-family: Arial; font-size: 18px; min-height: 40px; width:300px; border:1px solid red; overflow:auto; white-space: nowrap; } 

La min-height:40px intègre la hauteur pour quand apparaît la barre de défilement horizontale. A min-height:20px s'élargira automatiquement lorsque la barre de défilement horizontale apparaît, mais cela ne fonctionne pas dans IE7 (bien que vous puissiez utiliser des commentaires conditionnels pour appliquer un style séparé si vous le désirez).

Voici une solution relativement simple qui utilise l'événement d'entrée contenteditable pour analyser le dom et filtrer les différentes saveurs de nouvelles lignes (donc il devrait être robuste contre copier / coller, glisser-déposer, taper sur le clavier, etc.). Il condense plusieurs Noms de texte dans des Noms de texte uniques, délimite les nouvelles lignes de TextNodes, tue BR et met un "affichage: en ligne" sur tout autre élément auquel il touche. Testé sur Chrome, aucune garantie ailleurs.

http://jsfiddle.net/tG9Qa/

Donc, pour la postérité: la solution la plus simple est de faire en sorte que votre responsable de produit modifie les exigences afin que vous puissiez effectuer une édition multiligne. C'est ce qui s'est passé dans notre cas.

Toutefois, avant que cela ne se produise, j'ai finalement réussi à créer un éditeur de texte enrichi en une seule ligne. Je l'ai enveloppé dans un plugin jQuery à la fin. Je n'ai pas le temps de le finir (il y a probablement des bugs dans IE, Firefox fonctionne mieux et Chrome fonctionne très bien – les commentaires sont clairsemés et parfois pas très clairs). Il utilise des parties de la bibliothèque Rangy (extraite parce que je ne voulais pas compter sur la bibliothèque complète) pour obtenir des positions d'écran de sélections afin de tester la position de la souris par rapport à la sélection (afin de pouvoir faire glisser les sélections et déplacer la case).

En gros, cela fonctionne en utilisant 3 éléments. Une div extérieure (la chose que vous appelez le plugin), qui débouche: caché, puis 2 niveaux de nidification à l'intérieur. Le premier niveau est absolument positionné, le deuxième niveau est le contentieux réel. Cette séparation est nécessaire, car sinon, certains navigateurs donneront les grippies d'éléments absolument positionnés, pour permettre à l'utilisateur de le déplacer …

En tout cas, il y a tout un tas de code pour déplacer l'élément absolument positionné autour de l'élément supérieur, ce qui permet de déplacer le contentement réel. Le contentement lui-même possède des espaces blancs, etc., etc., pour le forcer à rester une seule ligne.

Il existe également un code dans le plugin qui supprime tout ce qui n'est pas une image (comme br , tables, etc., etc.) à partir de n'importe quel texte collé / traîné dans la boîte. Vous avez besoin de certaines parties de ce (comme les brs, les paragraphes de décapage / normalisation, etc.) mais peut-être souhaitez-vous normalement garder les liens, em , strong et / ou un autre formatage.

Source: https://gist.github.com/1161922

Vérifiez cette réponse que je viens d'afficher. Cela devrait vous aider:

Comment créer un onglet ContentEditable de ligne unique HTML5 qui écoute Entrée et Ech

Voici le balisage HTML:

 <span contenteditable="false"></span> 

Voici jQuery / javascript:

 $(document).ready(function() { $('[contenteditable]').dblclick(function() { $(this).attr('contenteditable', 'true'); clearSelection(); $(this).trigger('focus'); }); $('[contenteditable]').live('focus', function() { before = $(this).text(); if($(this).attr('contenteditable') == "true") { $(this).css('border', '1px solid #ffd646'); } //}).live('paste', function() { }).live('blur', function() { $(this).attr('contenteditable', 'false'); $(this).css('border', '1px solid #fafafa'); $(this).text($(this).text().replace(/(\r\n|\n|\r)/gm,"")); if (before != $(this).text()) { $(this).trigger('change'); } }).live('keyup', function(event) { // ESC=27, Enter=13 if (event.which == 27) { $(this).text(before); $(this).trigger('blur'); } else if (event.which == 13) { $(this).trigger('blur'); } }); $('[contenteditable]').live('change', function() { var $thisText = $(this).text(); //Do something with the new value. }); }); function clearSelection() { if ( document.selection ) { document.selection.empty(); } else if ( window.getSelection ) { window.getSelection().removeAllRanges(); } } 

J'espère que ça aide quelqu'un !!!

Si vous voulez une autre façon de la résoudre autre que de changer les exigences, avec un petit display:table est entièrement possible =)

 .container1 { height:20px; width:273px; overflow:hidden; border:1px solid green; } .container2 { display:table; } .textarea { width:273px; font-size: 18px; font-weight: normal; line-height: 18px; outline: none; display: table-cell; position: relative; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; word-wrap: break-word; overflow:hidden; } 
 <div class="container1"> <div class="container2"> <div contenteditable="true" class="textarea"></div> </div> </div> 

Vous pouvez remplacer cette division par une saisie de texte (après que l'événement onclick soit appelé).
J'ai utilisé quelque chose de similaire à ce plugin et ça a bien fonctionné.

Avec jQuery, j'ai configuré un événement .keypress, puis testez e.keyCode == 13 (touche de retour) et si le retour est faux de l'événement et l'édition n'est pas capable de faire des multilignes

 $('*[contenteditable=yes]').keypress(function(e) { if(e.keyCode == 13 && !$(this).data('multiline')) { return false; } })