Recentemente encontrei uma função como esta ao trabalhar em um projeto: destacar palavras-chave em páginas da web.
Achei que seria uma operação simples que poderia ser realizada com a substituição do innerHTML, mas encontrei muitos problemas. Este artigo registra esses problemas e a solução final perfeita, esperando ser útil para amigos que tenham a mesma experiência. Se você está interessado apenas nos resultados, ignore o processo e pule para ver os resultados ~
Prática comum: substituição regularIdeia: Se quiser destacar elementos, você precisa extrair as palavras-chave e envolvê-las em tags, e então ajustar o estilo das tags. Use innerHTML ou outHTML, mas não innerText ou outText.
const regex = new RegExp(keyword,g)element.innerHTML = element.innerHTML.replace(regex,<b class=a>+keyword+</b>)element.classList.add(destaque)
Os perigos ocultos de fazer isso são os seguintes:
()/div<div id=parent> <div class=test>teste</div> </div>
A palavra-chave elemento do nó pai executa o processamento de tingimento de fundo por meio da classe, o que polui o DOM original até certo ponto e pode afetar o reposicionamento do elemento. (Como plug-in, esperamos alterar o mínimo possível o DOM original)
Otimização regular um: processe apenas elementos localizados dentro de tagsvar formatKeyword = text.replace(/[-////^$*+?.()|[/]{}]/g, '//$&') // Escape dos caracteres especiais contidos na palavra-chave, Por exemplo, /.var finder = new RegExp(>.*?++.*?<) // Extraia o texto localizado na tag para evitar operação incorreta de classe, id, etc. element.innerHTML.replace(finder,function(matched){ return matched.replace(text,<br>+text+</br>)})//Substitua palavras-chave no texto extraído dentro da tag
Isso pode resolver a maioria dos problemas, mas o problema que ainda existe é que, enquanto houver um símbolo < semelhante no atributo tag, as regras de correspondência serão quebradas e o conteúdo de extração regular estará errado. O conjunto de dados HTML5 pode personalizar qualquer conteúdo. então esses caracteres especiais são inevitáveis.
<div dataset=p>d>Substituir</div>Otimização regular 2: limpar tags que podem ser afetadas
<div id=keyword>keyword</div> =》Substitua a tag de fechamento por uma variável [replaced1]keyword[replaced2]//O id=keyword na tag de fechamento não será processado=》[replaced1]<b>keyword </b >[replaced2] =》Substitua a variável temporária substituída pela tag original <div id=keyword><b>keyword</b></div>
Mais importante ainda, este método não pode extrair corretamente a tag quando o valor da tag contém o símbolo <>.
Em suma, após N muitas tentativas, diversas situações não foram tratadas de forma eficaz através da regularização. Então mudei de ideia e processei por meio de nós em vez de strings. element.childNodes pode limpar de forma mais eficaz as informações de interferência nas tags.
[Solução perfeita] Processamento por meio de nós DOM<div id=parent> palavra-chave 1 <span id=child> palavra-chave 2 </span> </div>
Obtenha todos os nós filhos por meio de parent.childNodes. O nó filho pode ser substituído por innerText.replce(keyword,result)
para obter o efeito de destaque desejado, como segue: <span id=child><b>keyword</b> 2</span>
(Processamento recursivo: quando filho A operação de substituição é executada quando o nó não contém nós filhos).
No entanto, a palavra-chave 1 é um nó de texto e só pode modificar o conteúdo do texto, não pode adicionar HTML e não pode controlar seu estilo de forma independente. Os nós de texto não podem ser convertidos em nós comuns, o que também é o mais angustiante.
Finalmente, aqui vem o foco deste artigo. Por causa dessa função, tive contato sério com nós de texto pela primeira vez. A partir daqui descobri o Texto e usei o método de cortar nós de texto e substituí-los para obter destaque.
Código-fonte e destaques de restauração, consulte o código-fonte
const reg = new RegExp(keyword.replace(/[-////^$*+?.()|[/]{}]/g, '//$&'))highlight = function (node,reg ){ if (node.nodeType == 3) { //Processar apenas nós de texto const match = node.data.match(new RegExp(reg)); document.createElement(b); destaqueEl.dataset.highlight=y const wordNode = node.splitText(match.index) wordNode.splitText(match[0].length); wordNew = document.createTextNode(wordNode.data); destaqueEl.appendChild(wordNew);//destacar O nó foi construído com sucesso wordNode.parentNode.replaceChild(highlightEl, wordNode); // Substitua o nó de texto} } else if (node.nodeType == 1 && node.dataset.highlight!=y ) { for (var i = 0 ; eu < node.childNodes.length; i++) { destaque(node.childNodes[i], reg);Resumir
O texto acima é a solução perfeita para destacar palavras-chave em HTML introduzidas pelo editor. Espero que seja útil para você. Se você tiver alguma dúvida, deixe-me uma mensagem e o editor responderá a tempo. Gostaria também de agradecer a todos pelo apoio ao site de artes marciais VeVb!