使用.replace()突出显示页面上的文字。 [英] Highlight a word of text on the page using .replace()
问题描述
我正在开发Google Chrome扩展程序,该扩展程序允许您自动将突出显示CSS规则应用于您选择的单词。
I'm developing a Google Chrome extension that allows you to automatically apply a highlighting CSS rule to a word that you choose.
我有以下代码
var elements = document.getElementsByTagName('*');
for (var i=0; i<elements.length; i++) {
var element = elements[i];
for (var j=0; j<element.childNodes.length; j++) {
var node = element.childNodes[j];
if(node.nodeType === 3) {
var text = node.nodeValue;
var fetchedText = text.match(/teste/gi);
if(fetchedText) {
var replacedText = element.innerHTML.replace(/(teste)/gi, "<span style=\"background-color: yellow\">$1</span>");
if (replacedText !== text) {
element.innerHTML = replacedText;
}
}
}
}
}
其中会打破并冻结我的Chrome选项卡。但是,如果我从 element.innerHTML = replacedText;
切换为 element.innerHTML =text;
这可行。
Which breaks and freezes my Chrome tab. However, if I switch from element.innerHTML = replacedText;
to element.innerHTML = "text";
this works.
我找不到下面的代码有什么问题。
I can't seem to find what's wrong with the following code.
推荐答案
我遇到的错误是由于递归循环引起的,例如,我正在寻找关键字 teste
,并且我正在插入一个带有内容的新元素< span style = \background-color:#ffff00\> teste< / span>
这将强制脚本尝试替换新关键字 teste
再等等。
The error I was experiencing was due to a recursive loop because, for instance, I was looking for the keyword teste
and I was inserting a new element with the content <span style=\"background-color: #ffff00\">teste</span>
which would force the script to try to replace the new keyword teste
again and so on.
我想出了这个函数:
I came up with this function:
function applyReplacementRule(node) {
// Ignore any node whose tag is banned
if (!node || $.inArray(node.tagName, hwBannedTags) !== -1) { return; }
try {
$(node).contents().each(function (i, v) {
// Ignore any child node that has been replaced already or doesn't contain text
if (v.isReplaced || v.nodeType !== Node.TEXT_NODE) { return; }
// Apply each replacement in order
hwReplacements.then(function (replacements) {
replacements.words.forEach(function (replacement) {
//if( !replacement.active ) return;
var matchedText = v.textContent.match(new RegExp(replacement, "i"));
if (matchedText) {
// Use `` instead of '' or "" if you want to use ${variable} inside a string
// For more information visit https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
var replacedText = node.innerHTML.replace(new RegExp(`(${replacement})`, "i"), "<span style=\"background-color: #ffff00\">$1</span>");
node.innerHTML = replacedText;
}
});
}).catch(function (reason) {
console.log("Handle rejected promise (" + reason + ") here.");
});
v.isReplaced = true;
});
} catch (err) {
// Basically this means that an iframe had a cross-domain source
if (err.name !== "SecurityError")
{ throw err; }
}
}
在修改node属性和tell我已经修改了那个节点,所以我不会再次返回递归的无限循环。
Where I modify the node property and "tell" that I've already modify that node so I don't end up on a recursive infinite loop again.
PS正如你可以看到这个解决方案使用jQuery。我会试着重写这个只使用Vanilla JS。
P.S. As you can see this solution uses jQuery. I'll try to rewrite this to use just Vanilla JS.
这篇关于使用.replace()突出显示页面上的文字。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!