En la siguiente estructura:
<div contenteditable="true"> <span class="some-class">Hello</span> World <!-- no span here --> <span class="some-other-class">and good bye!</span> </div>
¿Es posible eliminar los elementos de intervalo seleccionados, pero no el nodo de texto, sin interrumpir la posición del cursor en el div
contenteditable
?
Entonces, incluso si el cursor está dentro del lapso, mantenga el mismo contenido de texto, pero simplemente elimine los elementos del lapso que lo rodean.
Por ejemplo, si el estilo de some-class
es de color de texto rojo y coloco el cursor en algún lugar dentro de la palabra "Hola", entonces quiero que desaparezca el estilo y elimine el span
ajuste.
¡Aqui tienes!
<div contenteditable="true"> <span class="some-class" style="color: red">Hello</span> <span class="some-class" style="color: blue">world</span> <span class="some-other-class" style="color: orange">and good bye!</span> <span style="color: green">test</span> </div> <script> const div = document.querySelector('div'); const getSelection = () => { let offset = 0; const selection = window.getSelection(); const range = selection.getRangeAt(0); let start = range.startOffset; let end = range.endOffset; if (selection.baseNode.parentNode.hasChildNodes()) { for (const node of selection.baseNode.parentNode.childNodes) { const cnode = node; if (cnode.nodeType == document.TEXT_NODE && !(offset + cnode.length > start)) { offset = offset + cnode.length; } if (cnode.nodeType == document.ELEMENT_NODE && !(offset + cnode.textContent.length > start)) { offset = offset + cnode.textContent.length; } } } start = start + offset; end = end + offset; return { start, end }; }; const removeSpan = ({ target, currentTarget: { selectionStart } }) => { // Get our selection points for within our span element const { start, end } = getSelection(); // Only run this logic for span elements if (target.tagName === 'SPAN') { // Create new text node from our span's innerText const text = document.createTextNode(target.innerText + ' '); // Replace span with just the text target.replaceWith(text); // Create a range and set selection range back to what it was to not affect cursor const range = document.createRange(); range.setStart(text, start); range.setEnd(text, end); const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } }; div.addEventListener('click', removeSpan); </script>