Recientemente encontré una función como esta cuando trabajaba en un proyecto: resaltar palabras clave en páginas web.
Pensé que sería una operación simple que podría lograrse con el reemplazo de InnerHTML, pero encontré muchos problemas. Este artículo registra estos problemas y la solución final perfecta, con la esperanza de ser útil para amigos que tengan la misma experiencia. Si solo estás interesado en los resultados, ignora el proceso y salta para ver los resultados~
Práctica común: reemplazo regularIdea: si desea resaltar elementos, debe extraer las palabras clave, envolverlas en etiquetas y luego ajustar el estilo de las etiquetas. Utilice internalHTML o outHTML, pero no internalText ni outText.
const regex = new RegExp(palabra clave,g)element.innerHTML = element.innerHTML.replace(regex,<b class=a>+keyword+</b>)element.classList.add(resaltado)
Los peligros ocultos de hacer esto son los siguientes:
()/div<div id=padre> <div clase=prueba>prueba</div> </div>
El elemento del nodo principal de la palabra clave realiza un procesamiento de teñido de fondo a través de la clase, lo que contamina el DOM original hasta cierto punto y puede afectar el reposicionamiento del elemento. (Como complemento, esperamos cambiar el DOM original lo menos posible)
Optimización regular uno: solo elementos de proceso ubicados dentro de etiquetas var formatKeyword = text.replace(/[-////^$*+?.()|[/]{}]/g, '//$&') // Escape de los caracteres especiales contenidos en la palabra clave, Por ejemplo, /.var finder = new RegExp(>.*?++.*?<) // Extrae el texto ubicado en la etiqueta para evitar un mal funcionamiento de clase, id, etc. element.innerHTML = element.innerHTML.replace(finder,function(matched){ return matched.replace(text,<br>+text+</br>)})//Reemplazar palabras clave en el texto extraído dentro de la etiquetaEsto puede resolver la mayoría de los problemas, pero el problema que aún existe es que mientras haya un símbolo < similar en el atributo de etiqueta, las reglas de coincidencia se romperán y el contenido de extracción regular será incorrecto. El conjunto de datos HTML5 puede personalizar cualquier contenido. por lo que estos caracteres especiales son inevitables.
<div dataset=p>d>Reemplazar</div>Optimización regular 2: borrar etiquetas que puedan verse afectadas
<div id=palabra clave>palabra clave</div> =》Reemplace la etiqueta de cierre con una variable [replaced1]palabra clave[replaced2]//La id=palabra clave en la etiqueta de cierre no se procesará=》[replaced1]<b>palabra clave </b >[replaced2] =》Reemplace la variable temporal reemplazada con la etiqueta original <div id=keyword><b>keyword</b></div>
Lo más importante es que este método no puede extraer correctamente la etiqueta cuando el valor de la etiqueta contiene el símbolo <>.
En resumen, después de N muchos intentos, varias situaciones no se han manejado de manera efectiva mediante la regularización. Luego cambié de opinión y lo procesé a través de nodos en lugar de cadenas. element.childNodes puede limpiar de forma más eficaz la información de interferencia en las etiquetas.
[Solución perfecta] Procesamiento a través de nodos DOM<div id=parent> palabra clave 1 <span id=child> palabra clave 2 </span> </div>
Obtenga todos los nodos secundarios a través de parent.childNodes. El nodo secundario se puede reemplazar por innerText.replce(keyword,result) para obtener el efecto de resaltado deseado, de la siguiente manera: <span id=child><b>keyword</b> 2</span> (Procesamiento recursivo: cuando el nodo secundario La operación de reemplazo se realiza cuando el nodo no contiene nodos secundarios).
Sin embargo, la palabra clave 1 es un nodo de texto y solo puede modificar el contenido del texto, no puede agregar HTML y no puede controlar su estilo de forma independiente. Los nodos de texto no se pueden convertir en nodos ordinarios, lo cual también es lo más angustiante.
Finalmente ~, aquí viene el enfoque de este artículo. Debido a esta función, entré en contacto serio con los nodos de texto por primera vez. Desde aquí descubrí Texto y utilicé el método de cortar nodos de texto y reemplazarlos para lograr resaltar.
Código fuente y aspectos destacados de restauración ver código fuente
const reg = new RegExp(keyword.replace(/[-////^$*+?.()|[/]{}]/g, '//$&'))highlight = función (nodo,reg ){ if (node.nodeType == 3) { //Solo procesa nodos de texto const match = node.data.match(new RegExp(reg)); document.createElement(b); resaltaEl.dataset.highlight=y const wordNode = node.splitText(match.index) wordNode.splitText(match[0].length // Cortar en tres nodos de texto después de la primera palabra clave y const); palabraNueva = document.createTextNode(wordNode.data); resaltadoEl.appendChild(palabraNueva);//resaltado El nodo se creó correctamente wordNode.parentNode.replaceChild(highlightEl, wordNode); // Reemplazar el nodo de texto} } else if (node.nodeType == 1 && node.dataset.highlight!=y ) { for (var i = 0 ; i < nodo.childNodes.length; i++) { resaltar(node.childNodes[i], i++ } } } ResumirLo anterior es la solución perfecta para resaltar palabras clave en HTML introducidas por el editor. Espero que le resulte útil. Si tiene alguna pregunta, déjeme un mensaje y el editor le responderá a tiempo. ¡También me gustaría agradecer a todos por su apoyo al sitio web de artes marciales VeVb!