【问题标题】:How to add style for specific words at HTML using JavaScript?如何使用 JavaScript 在 HTML 中为特定单词添加样式?
【发布时间】:2021-08-25 21:34:46
【问题描述】:

有人能帮我写一个 JS 函数,它将一个字符串(单词)作为参数吗? 然后为 HTML 中的所有这些单词添加额外的样式(例如更改颜色)。我不知道它的位置。这个“词”可以在<div>,或<p>,甚至<b>中。

示例:

HTML:

<p id="p1">Hello World!</p>
<div>Hello World!</div>

function Change(string word){
  //change font color to red
}

调用函数:

Change("Hello")

结果:

HTML 中的所有“Hello”字都有红色字体颜色。

顺便问一下,这样写可以吗?

【问题讨论】:

  • 您好,这里的基本问题是您如何定义“单词”?是否出现前后有非字母字符的字符串?您得到的答案可能会改变给定字符串的任何出现。

标签: javascript html css dom dom-events


【解决方案1】:

这是最好的解决方案。它适用于任何 html,只需调用 matchText("text","black","red");

function replaceInElement(element, find, replace) {
    for (let i= element.childNodes.length; i-->0;) { 
        let child= element.childNodes[i];
        
        if (child.nodeType==1) { 
            let tag= child.nodeName.toLowerCase();  
            if (tag!='style' && tag!='script') 
                replaceInElement(child, find, replace); 
        } else if (child.nodeType==3) { 
            replaceInText(child, find, replace);
        }
    }
}
function replaceInText(text, find, replace) {
    let match; 
    let matches= [];
    
    while (match= find.exec(text.data)){ 
        matches.push(match);
    }
    
    console.log(matches);
    for (let i= matches.length; i-->0;) {
        match = matches[i];

        text.splitText(match.index); 
        text.nextSibling.splitText(match[0].length);

        text.parentNode.replaceChild(replace(match), text.nextSibling); 
    }
}

let matchText = (word, backColor, textColor) => {
    let regexp = new RegExp(`\\b(${word})\\b`, 'gmi');

    replaceInElement(document.body, regexp, function(match) { 

        var elem= document.createElement('span'); 
        elem.style.backgroundColor = backColor;
        elem.style.color = textColor;

        elem.appendChild(document.createTextNode(match[0]));
        return elem;
    });
}

【讨论】:

    【解决方案2】:

    CSS 是为样式而生的。使用 JS 将类添加到您的 HTML 元素中。

    功能:

    传递 string 进行搜索,传递 selector/s 进行搜索,在我的例子中,我正在搜索 DOM 中的所有标签并返回一个数组 [...document.getElementsByTagName('*')]

    我们定义了一个数组来保存我们想要搜索的非限制元素,另一个保存限制 em> 我们要跳过的标签。然后我们用!restricted.includes(tag.nodeName.toLowerCase() 循环output 数组,这会检查我们的restricted 数组是否不包含 em> 来自我们的 DOM 查询的元素。对于返回 true 的元素,我们将它们推送到我们的 output 数组中 --> output.push(tag)

    一旦我们的 output 数组填充了我们想要搜索的标签,我们就会在标签中搜索我们的 string --> tag.innerText.includes(string)非常重要: !(tag.textContent.match(/\n/g)||[]).length 将确保它是正确的子节点,如果返回 true,我们将替换标签 innerHTML 并简单地换行我们的带有 span 标签的字符串现在包含一个按照我们想要的样式设置样式的类 -->

    tag.innerHTML = tag.innerText.replace(string, `<span class="red">${string}</span>`)
    

    const els = [...document.getElementsByTagName('*')]
    const string = "Hello"
    
    function Change(string, els) {
      const restricted = ['html', 'body', 'head', 'style', 'meta', 'script']
      const output = []
      els.forEach(tag => !restricted.includes(tag.nodeName.toLowerCase()) ? output.push(tag) : null)
      output.forEach(tag => tag.innerText.includes(string) && !(tag.textContent.match(/\n/g) || []).length ? tag.innerHTML = tag.innerText.replace(string, `<span class="red">${string}</span>`) : null)
    }
    
    Change(string, els)
    .red {
      color: red;
    }
    <p id="p1">Hello World!</p>
    <div>Hello World...</div>
    
    <div>
      <ul>
        <li>Hello World.</li>
      </ul>
    </div>
    
    <p>
      <a href="#">Hello <span>World</span></a>
    </p>
    
    <table border="1">
    <tr>
      <th>Hello</th><th>World</th>
      </tr>
    <tr>
      <td>World</td><td>Hello</td>
      </tr>
    </table>

    【讨论】:

    • 标签未定义
    • 什么标签没有定义?
    • @bodkia22 标签由 forEach 方法隐式定义,array => 元素(标签)。数组中的每个元素都定义为 forEach 括号内的给定元素名称,在我的示例中,我使用了单词tag。否则 JS 会在控制台中抛出错误。你运行了代码片段吗?
    • 这是有史以来最好的变种!因为它不影响属性。
    • 我可以把 els 放到脚本里吗?函数更改(字符串){ const els = [...document.getElementsByTagName('*')]......
    【解决方案3】:

    这是一种查找单词并将其替换为&lt;span class='red'&gt; word &lt;/span&gt; 的方法。我已经用这种风格设置了一个名为“red”的类。这是非常基本的,但适用于简单的应用程序。下面的cmet中有解释

    function Change(word) {
      //find all html elements on the page inside the body tag
      let elems = document.querySelectorAll("body *");
      // get our replacement ready
      let span = "<span class='red'>" + word + "</span>";
      //loop through all the elements
      for (let x = 0; x < elems.length; x++) {
        // for each element, 'split' by the word we're looking for, then 'join' it back with the replacement
        elems[x].innerHTML = elems[x].innerHTML.split(word).join(span);
      }
    }
    
    Change('Hello', 'Goodbye');
    .red {
      color: red;
    }
    <p id="p1">Hello World!</p>
    <div>Hello World!</div>

    【讨论】:

      【解决方案4】:

      这是一个非常基本的示例。请注意,虽然这是不区分大小写的,但它将用您提供的任何大小写替换所有出现的情况。例如,在下面的块中,我输入了"Hello",它将hello 的出现设置为Hello。您当然可以删除正则表达式标志中的 i 以使其再次区分大小写,但您必须在两种情况下运行该函数两次以突出显示这两个实例。

      function color(str, color)
      {
        var rx = new RegExp(str, "ig");
        var replaced = document.body.innerHTML.replaceAll(rx, "<span style='color:"+color+"'>"+str+"</span>");
        document.body.innerHTML = replaced;
      }
      
      color("Hello", "red");
      <p>Hello world</p>
      <p>This block contains the word "hello."</p>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        相关资源
        最近更新 更多