web-dev-qa-db-fra.com

Comment désactiver la sélection et le redimensionnement d'éléments dans contenteditable div?

Par exemple. J'ai la disposition suivante:

<div contenteditable="true">
   <span class="text-block" contenteditable="false">
      <span contenteditable="false">Name</span>
      <a href="javascript:void(0)">
          <i class="small-icon-remove"></i>
      </a>
   </span>
​</div>

Alors, comment désactiver ceci:

enter image description here

et ça: 

enter image description here

27
Andrei

J'y ai passé beaucoup de temps moi-même, lorsque j'essayais de masquer complètement les sélections de contrôle (c'est comment elles sont appelées) dans CKEditor du widgets . Malheureusement, je n'ai pas de bonnes nouvelles.

Solution 1

Tout d’abord, il existe un événement mscontrolselect . Quand je l’ai trouvé (et le fait que son nom porte un préfixe ms), j’étais très heureux, car selon MS , il devrait être évitable.

Mais il s'est avéré que c'est totalement instable. Parfois, il est congédié, parfois non. Cela varie entre les versions d'IE, la structure DOM, les attributs, l'élément sur lequel vous cliquez, est-ce un élément de bloc, etc. La merde habituelle de la MS. Mais tu peux essayer:

function controlselectHandler(evt) {
    evt.preventDefault();
}
document.body.addEventListener('mscontrolselect', controlselectHandler);

Cependant, cela bloquera complètement la sélection (si cela a fonctionné). Donc, vous rendrez ces éléments non sélectionnables du tout.

Solution 2

Ensuite, il existe une deuxième option, plus fiable: déplacer la sélection ailleurs après avoir cliqué sur cet élément. Cela peut être mis en œuvre de différentes manières. Dans CKEditor, nous corrigeons la sélection sur mousedown... et mouseup car (encore) parfois, cela ne suffit pas pour IE et cela dépend de dizaines de conditions. Vous pouvez également écouter l'événement selectionchange et corriger la sélection à cet endroit.

Cependant, encore une fois, nous parlons également de bloquer la sélection d'un tel élément.

Solution 3

Par conséquent, la troisième option consiste à bloquer non pas la sélection mais l'événement resizestart. CKEditor combine cela avec la commande enableObjectResizing: https://github.com/ckeditor/ckeditor-dev/blob/a81e759/plugins/wysiwygarea/plugin.js#L211-L218 . Cette solution empêchera le redimensionnement, mais ne masquera bien sûr pas ces frontières laides.

Solution 4

Comme je l'ai mentionné, j'ai travaillé sur ce problème dans CKEditor. Nous avons réussi à rendre possible l’intégration d’éléments non modifiables, mais avec un comportement entièrement contrôlable et unifié entre les navigateurs. La solution complète est trop complexe pour être expliquée sur StackOverflow et il nous a fallu des mois pour la mettre en œuvre. Nous avons appelé cette fonctionnalité widgets. Voir quelques démos ici . Comme vous pouvez le constater, il n'y a pas de sélection de contrôle lorsque l'élément non modifiable est sélectionné. La sélection apparaît sur un court instant seulement entre mousedown et mouseup, mais seulement dans des cas spécifiques. Sauf que tout fonctionne comme s'il était natif (bien que ce soit une chose complètement fausse).

Plus d'informations dans le Introduction aux widgets et dans le Widgets Tutorial .

23
Reinmar

Ce message était essentiel pour résoudre ce problème pour moi (fonctionne dans tinyMCE):

Comment supprimer les poignées de redimensionnement et la bordure de div avec le style contentEditable and size

En plaçant une DIV contentable dans une DIV non contentable, les descripteurs n'apparaissent pas dans IE ou dans FF, mais vous pouvez toujours modifier le contenu.

Ex.

<div class="outerContainer" contenteditable="false">
    <div class="innerContainer" contenteditable="true">
    </div>
</div>
10
Baron

Solution 5

Lorsque le focus est déplacé sur le contrôle enfant, définissez la valeur de l'attribut d'élément éditable sur le contenu sur false. De la même manière, dès que votre focus quitte le contrôle enfant, définissez le contenu editable sur true. 

5
user3698559

Pour désactiver les poignées de redimensionnement, tout ce que je devais faire était d’ajouter ce qui suit pour IE11:

div {
    pointer-events: none;
}

Pour que Firefox exécute cette ligne après l’insertion de l’élément contenteditable:

document.execCommand("enableObjectResizing", false, false);
3
Kevin Lee

Pour moi, le problème a été de supprimer une ligne max-width: 100% !important; des propriétés CSS des éléments DOM de la variable contenteditable. J'espère que ça aide!

BTW cela ne se produit pas sur MS Edge ... les doigts croisés que cela montre un mouvement dans la bonne direction par MS :)

1

J'ai le même problème avec CKEditor 4.4.7 dans IE11. Pour résoudre ce problème, enregistrez les dimensions actuelles d'un élément dans "mousedown" et définissez les propriétés de style "min-width", "max-width", "min-height" et "max-height" sur ses dimensions actuelles. De ce fait, l'élément sera affiché dans sa taille originale lors du redimensionnement. Sur "mouseup" je restaure les propriétés de style de l'élément modifié. Voici mon code:

$('textarea').ckeditor().on('instanceReady.ckeditor', function(event, editor) {
    var $doc = $(editor.document.$);
    $doc.on("mousedown", "table,img", function() {
        var $this = $(this);
        var widthAttrValue = $this.attr("width");
        if (widthAttrValue) {
            $this.data("widthAttrValue", widthAttrValue);
        }
        var widthStyleValue = this.style.width;
        if (widthStyleValue) {
            $this.data("widthStyleValue", widthStyleValue);
        }
        var width = widthStyleValue || widthAttrValue || String($this.width())+"px";
        var height = this.style.height || $this.attr("height") || String($this.height())+"px";
        $this.css({
            "min-width": width,
            "max-width": width,
            "min-height": height,
            "max-height": height,                                       
        });
        $doc.data("mouseDownElem",$this);
    }).on("mouseup", function() {
        var $elem = $doc.data("mouseDownElem");
        if ($elem) {
            $elem.removeAttr("height").css("height","");
            var widthAttrValue = $elem.data("widthAttrValue");
            if (widthAttrValue) {
                $elem.attr("width", widthAttrValue);
                $elem.removeData("widthAttrValue");
            } else {
                $elem.removeAttr("width");
            }
            var widthStyleValue = $elem.data("widthStyleValue");
            if (widthStyleValue) {                                      
                $elem.removeData("widthStyleValue");
            } 
            $elem.css({
                "min-width":"",
                "max-width":"",
                "min-height":"",
                "max-height":"",
                "width": widthStyleValue || ""
            });
            if (!$.trim($elem.attr("style"))) {
                $elem.removeAttr("style");
            }
            $doc.removeData("mouseDownElem");
        }
    });
});
1
Christof

"débordement caché;" peut également causer ce problème, comme:

ul, ol {
  overflow: hidden;
}
1
Oleg Zemelia Raban

J'ai eu le même problème. Il semble que, d'après les publications précédentes, certains comportements soient reconnus par IE et ajouteront ce paragraphe focus/redimensionner. Pour moi, c’est parce que j’avais un style pour les paragraphes de la division contenteditible.

Enlever:

div[contenteditble="true"] p{
   min-height:1em;
}

Corrigé pour moi.

1
user1364467

RESOLU! En plaçant la plage non modifiable du contenu dans un CORPS modifiable du contenu, il a commencé à afficher un conteneur SPAN pouvant être redimensionné. Ce qui a simplement résolu mon problème, c’est un style CSS simple et linéaire pointeur-événements: aucun; sur la balise intérieure SPAN.

min-width: 1.5cm;
display: inline-block;
pointer-events: none;
<body content-editable="true">
  <span>Sample Text</span>
</body>

0
Mohtashim Shamsi

Rien de ce que quelqu'un d'autre n'a recommandé ici ou dans d'autres discussions n'a vraiment fonctionné pour moi, mais je l'ai résolu en faisant:

[contenteditable="true"] p:empty {
    display: inline-block;
}

De cette façon, les boîtes de redimensionnement ont disparu, mais je pouvais toujours placer mon curseur au-dessous ou dans les blocs P pour les éditer.

0
Ezra

J'ai eu le même problème parce que je mets des règles CSS pour la largeur maximale sur tous les éléments enfants dans le contenteditable. Le supprimer ou le limiter aux images a fait l'affaire.

[contenteditable] * { max-width: 100%; } // causes the issue
[contenteditable] img { max-width: 100%; } // works fine for me

Assurez-vous qu'aucun élément <p> n'est affecté par la propriété max-width.

0
retoheusser

Voici ce que j'ai fait pour résoudre ce problème. Pour moi, cela ne se produirait que lorsque l'élément contenteditable était vide et que les poignées de redimensionnement disparaissaient lorsqu'il y avait du contenu. J'ai donc créé la seule solution CSS suivante:

[contenteditable]:empty:after {
  content: " ";
}

L'idée derrière la solution est que chaque fois que le champ contenteditable est vide, il applique un pseudo-élément d'espace, supprimant ainsi les balises de redimensionnement qui apparaissent lorsque l'utilisateur sélectionne le champ contenteditable. Une fois que l'utilisateur a entré quelque chose, le pseudo-élément disparaît.

Notez qu'en raison de l'utilisation de pseudo-éléments, ce correctif ne fonctionne que sur IE9 et les versions ultérieures.

0
Nej Kutcharian