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 etiquetasvar 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 etiqueta
Esto 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++ } } }Resumir
Lo 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!