¿Cómo deshabilitar la selección y el cambio de tamaño de los elementos en contenteditable div?

Por ejemplo, tengo el siguiente layout:

<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> 

Entonces, como deshabilitar esto:

enter image description here

y esto:

enter image description here

Pasé mucho time en esto, cuando trato de ocultar por completo las selects de control (así es como se llaman) en los widgets de CKEditor . Lamentablemente, no tengo una buena noticia.

Solución 1

En primer lugar, hay un evento mscontrolselect . Cuando lo encontré (y el hecho de que su nombre tiene un prefijo ms ) me sentí muy feliz, porque de acuerdo con la EM debería ser prevenible.

Pero resultó que es totalmente inestable. A veces se dispara, otras veces no. Varía entre las versiones de IEs, la estructura DOM, los attributes, en qué elemento hace clic, es un elemento de bloque, etc. La basura habitual de MS. Pero puedes intentar:

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

Sin embargo, esto bloqueará por completo la selección (si funcionó). Por lo tanto, hará que esos elementos no sean seleccionables en absoluto.

Solución 2

Luego hay una segunda opción, más confiable: mover la selección a otro lugar luego de hacer clic en ese elemento. Hay pocas forms en que esto pueda implementarse. En CKEditor estamos arreglando la selección en mousedown … y mouseup porque (nuevamente) a veces no es suficiente para IE y depende de una docena de condiciones. También puede escuchar el evento selectionchange y corregir la selección allí.

Sin embargo, nuevamente, también estamos hablando de bloquear la selección de dicho elemento.

Solución 3

Por lo tanto, la tercera opción es bloquear no la selección, sino el evento resizestart . CKEditor combina esto con el command enableObjectResizing : https://github.com/ckeditor/ckeditor-dev/blob/a81e759/plugins/wysiwygarea/plugin.js#L211-L218 . Esta solución evitará el cambio de tamaño, pero por supuesto no ocultará esas feas fronteras.

Solución 4

Como mencioné, trabajé en este problema en CKEditor. Logramos hacer que los elementos no editables fueran editables, pero con un comportamiento completamente controlable y unificado entre los browseres. La solución completa es demasiado compleja para ser explicada en StackOverflow y nos tomó meses implementarla. Llamamos a esta característica widgets. Vea algunas demostraciones aquí . Como puede ver, no hay selección de control cuando se selecciona un elemento no editable. La selección aparece en un breve momento solo entre mousedown y mouseup , pero solo en casos específicos. Excepto por eso, todo funciona como si fuera nativo (aunque es una cosa completamente falsa).

Lea más en la Introducción a los widgets y en el tutorial de widgets .

Esta publicación fue fundamental al resolver este problema para mí (funciona en tinyMCE):

Cómo quitar el tamaño de los controlleres y el borde de div con contenidoEditable y estilo de tamaño

Al colocar un DIV contenteditable dentro de un DIV no contenteditable, los identificadores no aparecen en IE o FF, pero aún puede editar el contenido

Ex.

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

Solución 5

Cuando el foco se mueve al control infantil, cambie el valor del atributo del elemento editable de contenido a falso y de la misma manera, una vez que su enfoque abandona el control secundario, establezca nuevamente el contenido editable en verdadero.

Para deshabilitar los controlleres de cambio de tamaño, todo lo que tenía que hacer era agregar lo siguiente para IE11:

 div { pointer-events: none; } 

Para que Firefox ejecute esta línea después de que se haya insertado el elemento contenteditable, funciona:

 document.execCommand("enableObjectResizing", false, false); 

Tengo el mismo problema con CKEditor 4.4.7 en IE11. Como solución, guardo las dimensiones actuales de un elemento en "mousedown" y establezco las properties de estilo "min-width", "max-width", "min-height" y "max-height" en sus dimensiones actuales. Con eso, el elemento se mostrará en su tamaño original durante el cambio de tamaño. En "mouseup" restauro las properties de estilo del elemento modificado. Aquí está mi código:

 $('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"); } }); }); 

"desbordamiento: oculto"; también puede causar este problema, como:

 ul, ol { overflow: hidden; } 

Esto es lo que hice para solucionar este problema. Para mí, esto solo ocurriría cuando el elemento contenteditable estuviera vacío y los manejadores de cambio de tamaño desaparecerían cuando hubiera contenido, así que creé la siguiente solución de solo CSS para hacer esto:

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

La idea detrás de la solución es que cada vez que el campo contenteditable está vacío, aplica un pseudo elemento en blanco, lo que elimina las tags de cambio de tamaño cuando el usuario selecciona el campo contenteditable . Una vez que el usuario ha ingresado algo, el pseudo elemento desaparece.

Tenga en count que, debido al uso de pseudo-elementos, esta corrección solo funciona en IE9 y superior.

Lo que me solucionó el problema fue eliminar un max-width: 100% !important; línea de las properties CSS de los elementos DOM dentro de la DIV contenteditable . ¡Espero eso ayude!

Por cierto, esto no sucede en MS Edge … dedos cruzados que muestra un movimiento en la dirección correcta por MS 🙂

Yo tuve el mismo problema. Parece que de las publicaciones anteriores aquí hay ciertos comportamientos que IE reconoce y agregará este enfoque / cambio de tamaño de párrafo. Para mí fue porque tenía un estilo para los párrafos dentro de la split div contenta.

Eliminando:

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

Me lo arregló

Tuve el mismo problema porque puse reglas de CSS para el ancho máximo en todos los elementos secundarios dentro del contenteditable. Quitarlo o restringirlo a imágenes hizo el truco.

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

Asegúrese de que ningún elemento <p> se vea afectado por la propiedad de ancho máximo.