【问题标题】:Highlight Every Instance of String in <div> - Javascript突出显示 <div> 中的每个字符串实例 - Javascript
【发布时间】:2019-12-19 04:11:58
【问题描述】:

我在这里看到了多篇关于查找和突出显示字符串的帖子,但没有一个按预期工作。以下是我目前的脚本:

var str = 'word';
var divs= document.getElementsByClassName('strings');
for (var i = 0, len = divs.length; i < len; ++i) {
    if(divs[i].innerHTML.indexOf(str) !== -1) {
        // something
        console.log('YES');
        str.replace(/(\w+) (\w+)/, '<div class="strings">$1</div> <div class="strings">$2</div>');
    }else{
        console.log('NO');
    }
}

HTML:

<div class="strings">word word words</div>

理想情况下,每次 js 作为函数运行时,这会突出显示我的 div 中字符串的每个实例。

【问题讨论】:

  • 看看我刚才问的这个问题stackoverflow.com/questions/56773386/…
  • 您的预期输出是什么? “突出显示”是什么意思?添加CSS,添加&lt;mark&gt;标签?您的代码正在尝试创建一个可能是拼写错误的 &lt;div&gt;&lt;/span&gt; 元素。感谢您的澄清。
  • @ggorlen 这是一个错字谢谢,至于我想要的输出我不是 100% 确定。最终目标是有一个搜索表单,每次更改 js 函数时都会运行并突出显示(使用 css 或任何东西)输入黄色的字符串。更改background-color 可能是最简单的方法
  • edit你的问题表明这个问题与a simple search of this site可以找到的任何其他问题有何不同。
  • 也看看这个......看起来你很接近:stackoverflow.com/a/32130293/682232

标签: javascript


【解决方案1】:

您发布的代码在正确的轨道上,并且正则表达式替换很方便,但要非常小心,除了使用正确的逻辑之外,您不会通过清理您的代码来向XSS attacks 或正则表达式转义问题敞开心扉输入字段(尽管如果用户提供目标/源文本,XSS 问题将主要是问题)。

使用正则表达式上的"gi" 标志使您的搜索不区分大小写(我使用复选框进行切换),并在更新时随意循环您想要搜索的多个文本区域(我将其保留为一个为简单起见)。将\b 添加到正则表达式以强制执行严格的单词边界(在下面的示例中也可以切换)。您还可以在突出显示的元素上使用基本上任何元素或样式。 &lt;mark&gt; 似乎最符合语义。

最后,值得确保搜索词不包含空字符串,这会在文本的每个字符之间添加大量垃圾突出显示标签。

const escapeHTML = html => {
  const ta = document.createElement("textarea");
  ta.textContent = html;
  return ta.innerHTML;
};

const escapeRegex = s => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
  
const highlight = (searchTerm, originalText, caseIns, boundaries) => {
  const pattern = boundaries ? `(\\b${searchTerm}\\b)` : `(${searchTerm})`;
  return searchTerm ? originalText.replace(
    RegExp(pattern, "g" + (caseIns ? "i" : "")), "<mark>$1</mark>"
  ) : originalText;
};

const output = document.querySelector("#output");
const originalText = output.innerText;
let caseIns = false;
let boundaries = false;
let searchTerm = "";

document.querySelector("#ignore-case").addEventListener("change", e => { 
  caseIns = e.target.checked; 
  output.innerHTML = highlight(searchTerm, originalText, caseIns, boundaries);
});
document.querySelector("#word-boundaries").addEventListener("change", e => { 
  boundaries = e.target.checked; 
  output.innerHTML = highlight(searchTerm, originalText, caseIns, boundaries);
});
document.querySelector("input").addEventListener("keyup", e => {
  searchTerm = escapeHTML(escapeRegex(e.target.value));
  output.innerHTML = highlight(searchTerm, originalText, caseIns, boundaries);
});
div:first-child {
  display: flex;
  align-items: center;
  margin-bottom: 1em;
}

span {
  margin-left: 1em;
}

mark { /* add styling here */
  border-radius: 2px;
}
<div>
  <input placeholder="search term" />
  <span>Ignore case? <input type="checkbox" id="ignore-case" /></span>
  <span>Word boundaries? <input type="checkbox" id="word-boundaries" /></span>
</div>
<div id="output">Fourscore and seven years ago our fathers brought forth, on this continent, a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived, and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting-place for those who here gave their lives, that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we cannot dedicate, we cannot consecrate—we cannot hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they here gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth.</div>

【讨论】:

    【解决方案2】:

    您在针上而不是在干草堆上使用replace() 方法。您想在innerHTML 属性中找到str,然后将innerHTML 属性替换为使用`' 标记找到的给定str 周围的副本。

    因为您正在使用变量进行正则表达式搜索,所以您需要首先创建一个正则表达式对象并将针字符串注入其中。还给它g 标志,以便它匹配找到的正则表达式的每个实例:

    var regex = new RegExp(`${str}`, ['g']);
    

    然后你操作 div 元素的 innerHTML 属性:

    divs[i].innerHTML = divs[i].innerHTML.replace(regex, `<span class"highlighted">${str}</span>`);
    

    现在脚本将查找单词并用.highlighted 类包裹它。 所以现在剩下要做的就是修复 css 来处理它:

    .highlighted {
      background-color: yellow;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-30
      • 2018-10-16
      • 2023-04-07
      • 1970-01-01
      • 2022-12-07
      • 2022-01-01
      • 1970-01-01
      • 2020-06-23
      • 2011-09-04
      相关资源
      最近更新 更多