Réglage de la position du caret sur un noeud vide dans un élément contentEditable

Ma tâche est de configurer un caret de texte pour apparaître dans un nœud de span vide dans une contentEditable .

Ce qui suit ne me pose aucun problème sur Firefox 3.6:

 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="js/jquery-1.4.3.min.js"> </script> <style> #multiple { border: 1px solid #ccc; width: 800px; min-height: 20px; padding: 5px; outline: none; } </style> <script> $(document).ready(function(){ var contentEditable = document.getElementById('multiple'); var lastItem = contentEditable.getElementsByTagName('span').item(2); var selectElementText = function(el, win){ win = win || window; var doc = win.document, sel, range; if (win.getSelection && doc.createRange) { range = doc.createRange(); range.selectNodeContents(el); range.collapse(false); sel = win.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (doc.body.createTextRange) { range = doc.body.createTextRange(); range.moveToElementText(el); range.select(); } } contentEditable.focus(); selectElementText(lastItem); }); </script> <title>Range Selection Tasks (Make Me Want to Cry)</title> </head> <body> <div id="multiple" contentEditable="true"> <span style="color:red">First</span><span style="color:green">Second</span><span style="color:blue"></span> </div> </body> </html> 

… mais sur Webkit et IE, l'accent est mis sur l' avantdernière période. Je ne sais pas pourquoi. Cela fonctionne si je place un espace à l'intérieur de la dernière portée, mais je reçois une sélection de gamme d'un caractère.

Cela dit, il est acceptable d'avoir des espaces dans le dernier nœud si le caret est au tout début.

Toute l'aide pouvant etre apportée serait très appréciée. Merci d'avance.

Le modèle de sélection / gamme de IE est basé sur les index dans le contenu du texte, en négligeant les limites des éléments. Je crois qu'il est peut-être impossible de définir le focus d'entrée dans un élément en ligne sans texte. Certes, avec votre exemple, je ne peux pas définir la mise au point dans le dernier élément en cliquant sur ou sur les touches fléchées.

Il fonctionne presque si vous définissez chaque étendue pour display: block , bien qu'il existe encore un comportement très étrange, en fonction de l'existence de l'espace blanc dans le parent. Hacking l'affichage pour regarder en ligne avec des astuces comme flotteur, en ligne-bloc et position absolue font IE traiter chaque élément comme une boîte d'édition séparée. Des éléments de bloc positifs relatifs à côté de l'autre travaillent, mais cela n'est probablement pas pratique.

Si cela vous permet de mieux vous sentir, IE9 règle ce désagrément et adopte le modèle de gamme standard. (Hooray!)

Il est acceptable d'avoir des espaces dans le dernier nœud si le carnet est au tout début.

Je ferais probablement cela, à moins qu'un expert en sélection IE puisse penser à quelque chose de mieux. (Calling Tim Down!)

Définissez le innerHTML l'élément sur un caractère à largeur nulle:

 ('element').innerHTML = '&#200B'; 

Maintenant, la carret peut y aller.

J'ai trouvé une solution de contournement pour Webkit, je ne sais pas si quelqu'un l'a trouvé avant, mais au lieu d'ajouter de manière programmatique un espace de largeur nulle, vous pouvez faire la même chose avec la propriété de contenu css3 dans le sélecteur psuedo des éléments que vous souhaitez Placez le caret. Cela présente l'avantage que les caractères supplémentaires ne s'affichent pas dans le DOM et que l'utilisateur ne peut pas parcourir le carnet entre celui-ci. Donc, fondamentalement, il n'est pas nécessaire de nettoyer.

Pour que cela fonctionne pour tout élément enfant de votre élément éditable de contenu, ce serait quelque chose comme ceci:

 #mycontenteditableelement *:after { content: '\200B'; } 

Je n'ai pas vérifié complètement, mais je pense que c'est une solution de rechange complète.

L'application d'une hauteur minimale et d'une largeur minimale aux éléments à l'intérieur contentables avec un bloc en ligne peut bien fonctionner, bien que l'impact ait des effets secondaires involontaires:

 #multiple * { min-height: 1em; } span, b, strong, i, em, a, etc { display: inline-block; min-width: 1em; background-color: hsla(0, 50%, 50%, .5); /* this is only a visual aid; discard @ will */ vertical-align: middle; /* so elements w/ inline-block align w/ text correctly */ } 

Vous constaterez qu'il y a encore des problèmes, mais si vous êtes prêt à sacrifier certains problèmes pour un ensemble plus restreint d'autres, cela peut être si bon.

Pour moi, le contenu de la div contentative sur <br> fonctionne. J'ai essayé de le définir à nbsp; Mais cela crée un espace de caractère supplémentaire dans le div avant de commencer l'édition.

J'espère que cela t'aides.