Primera vez que pregunto algo aquí, espero ser lo suficientemente preciso. Estoy tratando de hacer una extensión simple para Chrome que resalte el texto seleccionado cuando presiono "H" en mi teclado, pero tengo un problema:
Para detectar cuándo el usuario presiona H y obtener el fragmento de texto que seleccionó:
window.addEventListener('keydown', e => { if(e.code == "KeyH") { var selected = window.getSelection() //SimpleHighLight(selected); ComplexHighLight(selected); } });He codificado una forma simple de hacer lo que quiero así:
function SimpleHighLight(selected){ var selectedText = selected.toString(); if(selectedText.length != 0) { var range = selected.getRangeAt(0); var element = selected.anchorNode.parentNode; var highlited = "<span style='background: rgb(255,255,0)'>" + selectedText + "</span>"; var reg = new RegExp(selectedText,"g"); var text = element.innerHTML.replace(reg, highlited); element.innerHTML = text; } }Funciona bien para fragmentos de texto en un elemento DOM único y cuando no hay otra aparición del texto seleccionado, pero quiero que funcione siempre, como en el caso de que mi texto seleccionado provenga de 2 párrafos diferentes.
Así que hice esto:
function ComplexHighLight(selected){ var selectedText = selected.toString(); if(selectedText.length != 0) { console.log(" Selection : " + selectedText); var range = selected.getRangeAt(0); if(!range.collapsed) { var startNode = range.startContainer; var startOffset = range.startOffset; var endNode = range.endContainer; var endOffset = range.endOffset; if(startNode == endNode) //Means that its in the same node element { var highlited = "<span style='background: rgb(255,255,0)'>" + selectedText + "</span>"; startNode.replaceData(startOffset, endOffset-startOffset, highlited); startNode.parentNode.innerHTML = startNode.nodeValue; } } } }Esa es solo una parte del problema en el que manejo cuando un fragmento de texto está en el mismo elemento (ya tengo demasiados problemas para manejar cuando el texto seleccionado proviene de varios elementos :()).
Sobre el papel, debería funcionar, pero el problema principal es que cuando lo hago: startNode.parentNode.innerHTML = startNode.nodeValue; la división <span> se le da a innerHTML como una cadena y no como algo HTML.
He trabajado alrededor de esto durante toda la noche, pero no puedo arreglarlo, ¿alguien tiene una idea de cómo debería hacerlo?