javascript - 突出显示 <div> 中字符串的每个实例 - Javascript

标签 javascript

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

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 中字符串的每个实例。

最佳答案

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

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

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

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>

关于javascript - 突出显示 <div> 中字符串的每个实例 - Javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57418748/

相关文章:

javascript - 使用人脸作为聊天网站的密码

javascript - 我如何居中这个 span 元素?

javascript - 如何在悬停时为 div.card-img-overlay 中的文本添加动画效果

javascript - 如何在我的 Angular Web 应用程序中导入或使用外部 JS 文件和函数

javascript - 将 HTML 输入值作为 JavaScript 函数参数传递

javascript - Chrome 扩展 : How to inject button to an onfocus div(texterea/input) in the page? 特别是在 Facebook 页面中

Javascript:转换对象

javascript - 如何在javascript(angularjs)中的数组中查找数组是否为空

knockout.js - 是否有一个公认的约定来处理用户输入之前为 "yes-no"的 "unset"下拉菜单?

javascript - 如何附加按比例缩小的大宽度 Canvas ,以使页面宽度不会变大