HTML contenteditable avec les non-modifiable îles

J'ai une sorte D'éditeur WYSIWYG basé sur le navigateur où les utilisateurs peuvent modifier des documents-templates.

Document-template est un html ordinaire avec quelques "codes de fusion placeholders" Spéciaux. Un tel modèle est "instancié" en remplaçant ces espaces réservés par des données provenant de DB. Ceci donne le document final - une instance du modèle.

Mon approche actuelle ressemble à ceci:

<div contenteditable>
  Sample template with <input type=button class="mergecode" value="MergeCode1">.
</div>

(échantillon en Ligne pour jouer avec: http://jsfiddle.net/tFBKN/ )

L'entrée n'est pas modifiable dans de tels cas et se comporte comme un bloc solide - exactement ce dont j'ai besoin. Les utilisateurs peuvent supprimer ces codes de fusion en cliquant sur DEL ou BACKSPACE comme tout autre caractère, etc. En ayant CSS approprié pour une telle entrée.mergecode je suis capable de réaliser look-n-feel que je veux.

Mais avec une telle approche, j'ai trois problèmes différents dans trois différents Samu:

  • IE-CSS { font:inherit } ne fait simplement pas travaillez là, donc si l'entrée est à l'intérieur de <b> comme ici <b><input value="test"></b> il n'hérite d'aucun style de police.
  • FF-copie de fragment qui contient <input> element supprime cette entrée du contenu du presse-papiers, donc l'opération "coller" insère tout mais pas les entrées.
  • GC-cliquez sur {BACKSPACE} immédiatement après le <input> produit des résultats bizarres ( bug)

alors je cherche d'autres idées sur la façon de représenter non modifiable inline-bloc à la fois "îles" en HTML.

Autre approche que j'ai essayé jusqu'à présent:

  • <span contenteditable="false">MergeCode1</span> - cela ne fonctionne pas car la plupart des UAs suppriment un tel noeud de la sélection. Il n'est donc pas possible, par exemple, d'appliquer <b> ou <i> sur le dessus de la sélection qui contient une telle portée.

d'autres idées?

27
demandé sur c-smile 2013-01-31 03:05:00

5 réponses

Je suis un développeur CKEditor. Nous avons une certaine expérience avec les éléments de lecture imbriqués (i.e. placeholder plugin et la fonctionnalité sur laquelle nous travaillons actuellement n ° 9764) et je n'ai pas de bonnes nouvelles. Vous devez gérer chaque comportement à la main si vous voulez avoir un look&feel cohérent. Il n'y a pas d'astuce pour corriger les navigateurs. Et beaucoup de choses (comme ceci avec des choses bizarres se produisant autour de la saisie sur GC) semblent être insolubles.

20
répondu Reinmar 2013-02-04 08:59:23

une autre idée qui semble prometteuse:

pour utiliser la portée vide avec ::before { content:"caption"; } qui devrait produire un bloc non modifiable représenté en in DOM comme un noeud n'ayant aucune position caret à l'intérieur.

Vous pouvez l'essayer ici http://jsfiddle.net/TwVzt/1/

Mais cette approche n'est pas exempte de problèmes (dans mon cas): Il n'y a aucun moyen de déclarer ::before en ligne en utilisant style attribut DOM et donc l'ensemble doit être déclaré dans CSS upfront. Mais l'ensemble des codes de fusion que j'ai est assez grand, même inconnu à l'avance dans certains cas d'utilisation. Soupir.

néanmoins mettre cette recette ici si quelqu'un aura de meilleures circonstances (ensemble connu de codes).

11
répondu c-smile 2013-02-02 03:04:06

je sais que c'est un vieux fil, que je suis tombé sur un problème similaire. J'avais juste besoin de quelques passages non modifiables dans editable div. Fini par mettre en place un HACK-AUTOUR comme...

$('#testDiv').on('keydown', function(e) { 
    var targetNode = getSelectionStart();
    if(targetNode != undefined && targetNode.nodeType === 1 && targetNode.nodeName == 'SPAN')    
    {
      var nodeHtmlString = targetNode.outerHTML;

      if(~nodeHtmlString.indexOf("nonEditable"))
      {
        e.preventDefault();
        e.stopPropagation();
      }
    }
});

function getSelectionStart() {
 var node = document.getSelection().anchorNode;
 return (node.nodeType == 3 ? node.parentNode : node);
}

Complet violon à https://jsfiddle.net/fxmb3nL6/20/

3
répondu Pravin 2015-12-30 14:46:38

Solution ci-dessous -- avec une petite mise en garde. Mais d'abord, vous êtes géniaux!

Je ne suis pas un expert JS ou HTML, mais je ne savais pas non plus jsfiddle.net. Donc, en lisant vos commentaires plus d'autres recherches en ligne, et quelques tests sur jsfiddle j'ai créé le code suivant qui a fonctionné.

<pre><code>
<div contenteditable="false" class="editor" readonly="true" UNSELECTABLE="ON">
    Sample template with <span class="mergecode test1" />.
    <span contenteditable> editable </span>
    <font color=red><span UNSELECTABLE="ON" contenteditable="false" readonly="true"
     UNSELECTABLE="ON">  uneditable1 </span></font>
    <span contenteditable> editable2 </span>
    <font color=red><span contenteditable=false readonly="true" UNSELECTABLE="ON"> uneditable3</span></font>  
    <span contenteditable> editable4 </span>
    <span contenteditable="false" readonly="true" UNSELECTABLE="ON"> uneditable5 </span>
< /div>
</code></pre>

si vous mettez cela dans jsfiddle sur chrome vous voyez que cela fonctionne dans chrome (et IE et FF mais un peu différemment), mais il semble y avoir une petite mise en garde.

Le la mise en garde est ce que votre clé de liaison fait avec Backspace! Dans mon cas, lorsque je sélectionne une phrase non éditable et que j'appuie sur backspace dans chrome, Cela semble rafraîchir, ou faire un "go to the last page"! J'ai fait les deux premiers undeditbles rouge (à gauche le dernier noir) de sorte que vous pouvez voir ce qui se passe. Je le teste sur jsfiddle en Chrome et en FF et en IE. Tous semblent avoir agi correctement, à quelques questions près.

Et je pense que c'est la logique de la façon dont il fonctionne. La première Div est le parent de haut niveau, et il est contenteditable= "false". Donc tout ce qu'il contient doit être inaltérable. À L'exception des enfants à l'intérieur de celui-ci qui ont la portée contenteditble="vrai" ils deviennent modifiables. Si vous héritez de vos parents, mais vous pouvez écraser comme un enfant.

j'ai aussi mis les balises readonly= "true" UNSELECTABLE=" ON " parce que j'ai lu quelque part à leur sujet. Et il a fallu plus de tests!!! NOTEZ s'il vous PLAÎT, j'ai dû prendre de la Police... en dehors de la portée, ou ça ne marcherait pas. Mais dans IE il a parfaitement fonctionné. Les uneditables étaient de n'importe quelle couleur je leur ai dit d'être et aucune quantité de simple, dourble, ou triple clic ne sélectionnerait les uneditbles dans jsfiddle!!! :- ) Pour Chrome simple clic n'a rien fait, double clic a sélectionné l'uneditable, et avec backspace il est allé un peu nuts! Il semblait que cela irait à la page précédente. Avec FF, les choses étaient un peu plus folles! Double clic a sélectionné l'uneditable et l'editable avant lui! Aucune idée de pourquoi.

Si quelqu'un peut comprendre et écrivez sur les problèmes avec Chrome et FF qui serait génial. Il serait bien d'avoir un double clic ou n'importe quel nombre de clics rapides pour ne pas travailler dans Chrome et FF trop. Encore une fois je tiens à souligner la portée... il semble devoir être à côté des uneditables et font... en dehors de l'étendue de mesure.

J'espère que tout cela a un sens.

2
répondu user96265 2014-09-25 23:28:07

Pour IE, essayez ceci:

<span contenteditable="true">Uneditable</span>

notez la valeur inverse de l'attribut contenteditable! Il défie tout le bon sens, mais il fonctionne - au moins dans IE8 et IE9. Cet élément non modifiable, vous pouvez déplacer et copier/coller. Il est cependant loin d'être parfait. E. g. si vous audacieux, une région qui englobe l'élément non modifiable, cela va infecter le contenu de l'élément non modifiable. Donc, vous devrez probablement utiliser certains scripts pour garder la raison de l'élément. Aussi la mise contenteditable= "true" décorera l'élément uneditable avec des poignées redimensionnables. Vous pouvez les désactiver à nouveau en mettant unselectable="on", mais cela empêchera l'objet d'être traîné. Encore une fois, vous devrez probablement compter sur un script pour restaurer la largeur et la hauteur.

-2
répondu meringue 2013-01-31 18:39:41