如果innerHTML包含x,y,z等,则replaceWith-需要针对多个innerHTML变体的解决方案

时间:2019-01-04 18:26:53

标签: javascript html json

我有一个简短的脚本,该脚本在innerHTML中查找具有特定文本的特定类,然后使用replaceWith替换整个元素。当只有一段特定的文本时,这种方法非常有用,但是我有几项要查找和替换。

下面的HTML代码得到了简化。基本上,还有另一个脚本可以找到特定的术语,并在这些术语首次出现时添加带有定义的弹出窗口。我想省略一些术语,但是不可能修改其他脚本。我提出的第一个解决方案涉及找到弹出窗口类,查看其innerHTML是否具有一致的开始(它将始终以term开头,紧随其后是span标签),然后将整个元素替换为term作为普通文本(“ term” )。

let glossaryTerms = document.getElementsByClassName('popup');
for (let x = 0; x < glossaryTerms.length; x++) {
    let term = glossaryTerms[x];
    let content = term.innerHTML.trim();
        if (content.includes('term\<span')) {
           term.replaceWith('term');
        }
}
<p>Sample text for this example. Then there's a word with a definition popup <a  href="#" class="popup #text">term<span class="popupBody">This is the definition text that appears in the popup eventually...</span></a>.</p>

该脚本可以正常工作,但是我可能要打几个字。

例如: 苹果 香蕉 仙人掌

以此类推。

这里的任何建议都将不胜感激。我想知道这些术语是否可以存储在JSON文件中,例如,但是我不知道从哪里开始。

1 个答案:

答案 0 :(得分:1)

提取第一个文本(在第一个子元素之前)的方法是:

node.childNodes[0].nodeValue.trim();

...,这将把span节点视为 second 节点,前提是前面有文本。

还有第二个问题:getElementsByClassName返回的集合是一个 live 集合,即,当用纯文本替换那些弹出节点时,实际上减小了该集合的大小。所以第二个元素突然变成第一个(索引0),但是循环增加了索引,所以您跳过一个节点。

一种解决方案是使用非实时替代项querySelectorAll

let terms = new Set(["apple", "pear"]); // Only do something for these terms
for (let node of document.querySelectorAll('.popup')) {
    let term = node.childNodes[0].nodeValue.trim();
    if (terms.has(term)) node.replaceWith(term);
}
<p>Sample text for this example. Then there's a word with a definition popup 
<a  href="#" class="popup #text">apple<span class="popupBody">
This is the definition text that appears in the popup eventually...</span></a>.</p>

<p>Sample text for this example. Then there's a word with a definition popup 
<a  href="#" class="popup #text">pear<span class="popupBody">
This is the definition text that appears in the popup eventually...</span></a>.</p>