- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发Google Chrome扩展程序,该扩展程序可让您将突出显示的CSS规则自动应用于您选择的单词。
我有以下代码
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;
}
}
}
}
}
element.innerHTML = replacedText;
切换到
element.innerHTML = "text";
,则可以使用。
最佳答案
您首先要测试#text
节点,以查看文本是否包含要突出显示的单词,然后对父元素的.innerHTML
进行替换。这有两个问题。
.innerHTML
时,将更改childNodes
数组。这样做的方式是在包含要替换文本的数组中进一步添加了一个节点。因此,当您继续扫描childNodes
数组时,总是会找到一个(新的)节点,其中包含要替换的文本。因此,再次替换它,在childNodes
数组中创建另一个具有较高索引的节点。无限重复。 .innerHTML
属性中的文本。虽然已经进行测试以确保要替换的文本实际上包含在文本节点中,但这不会阻止RegExp也替换元素的实际HTML中的任何匹配单词(例如src="yourWord"
,href="http://foo.com/yourWord/bar.html"
或尝试突出显示style
,color
,background
,span
,id
,height
,width
,button
,form
,input
等词。)。 <script>
或<style>
标记中的文本。 node.nodeType === 3
)。如果不进行检查,由于使用.innerHTML
更改HTML,您还将遇到以下可能的问题:.replace()
所做的更改,您最终可能会更改属性或实际的HTML标签。这可能会完全破坏页面布局和功能。 .innerHTML
时,将完全重新创建页面那部分的DOM。这意味着元素,尽管新元素可能是具有相同属性的相同类型,但是附加到旧元素的任何事件侦听器都不会附加到新元素。这会严重破坏页面的功能。 #text
节点的内容执行操作,而不需要对父节点的
.innerHTML
进行操作。因为您要创建其他HTML元素(例如,带有子
<span style="">
节点的新
#text
元素),所以会有些复杂。
.innerHTML
属性将在Object上创建此类属性(就像在任何Object上一样),但不会更改屏幕上显示的文本(即
#text
节点的实际值)。因此,它将无法完成您想要做的事情:它将不会创建父节点的任何新HTML子代。
<span>
,以包括您正在创建的新文本节点(
#text
节点中的文本不在您的彩色
<span>
中)以及您正在创建的可能有多个
<span>
元素中。这将导致用单个
#text
元素替换单个
<span>
节点。虽然这将创建其他后代,但将使父元素中的子代数保持不变。因此,任何依赖它的JavaScript都不会受到影响。鉴于我们正在更改DOM,因此没有办法可能不会破坏其他JavaScript,但这应将这种可能性降到最低。
<p>
节点,而不是其他两个示例中使用的
NodeIterator)。
#text
中的每个文本节点上执行所需替换的代码,并创建新的HTML,以使
document.body
在文本的一部分中有所不同:
function handleTextNode(textNode) {
if(textNode.nodeName !== '#text'
|| textNode.parentNode.nodeName === 'SCRIPT'
|| textNode.parentNode.nodeName === 'STYLE'
) {
//Don't do anything except on text nodes, which are not children
// of <script> or <style>.
return;
}
let origText = textNode.textContent;
let newHtml=origText.replace(/(teste)/gi
,'<span style="background-color: yellow">$1</span>');
//Only change the DOM if we actually made a replacement in the text.
//Compare the strings, as it should be faster than a second RegExp operation and
// lets us use the RegExp in only one place for maintainability.
if( newHtml !== origText) {
let newSpan = document.createElement('span');
newSpan.innerHTML = newHtml;
textNode.parentNode.replaceChild(newSpan,textNode);
}
}
let textNodes = [];
//Create a NodeIterator to get the text nodes in the body of the document
let nodeIter = document.createNodeIterator(document.body,NodeFilter.SHOW_TEXT);
let currentNode;
//Add the text nodes found to the list of text nodes to process.
while(currentNode = nodeIter.nextNode()) {
textNodes.push(currentNode);
}
//Process each text node
textNodes.forEach(function(el){
handleTextNode(el);
});
关于javascript - 使用.replace()在页面上突出显示一个单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40710728/
我正在从一个旧数据库中选择数据,该数据库有一个滥用状态列。状态列中包含多条信息。值如“新联系人 YYYY”、“在线 YYYY”、“更新 YYYY”、“撤回 YYYY”等……。您可能已经猜到了,YYYY
我想使用ant的replace任务替换这样的文件之一中的 token : 版本.txt version.number=${versionNumber} build.gradle task writeV
sorted_elems 列表中有一些元素将被更改为 str 例如: sorted_elems = ['[abc]', '[xyz]', ['qwe']] 我想删除定义的字符 - [, ], ' 并打
如果替换在变量中传递,第一次和第二次替换是否等效? #!/usr/bin/env perl6 use v6; my $foo = 'switch'; my $t1 = my $t2 = my $t3
我正在做一个本地测试来比较 C# 中 String 和 StringBuilder 的 Replace 操作性能,但是对于 String 我使用了以下代码: String str = "String
我看到了所有内容,没有看到使用“--replace”的方式的内容。 如何在 wkhtmltopdf 中使用“--replace”。 请给我一个例子,谢谢。:) 最佳答案 假设您有一个页脚 my_foo
我需要在 50 多个文件中进行大量搜索/替换,并且正在使用 Sublime Text 3。 有没有办法逐步执行并交互确认每个更改?我不想要只执行所有替换的一揽子“全部替换”操作。 我正在思考 vi/v
那么“replace ”属性如何与 composer 一起使用? ?我已经阅读了 Composer 文档,但仍然不明白。搜索更多信息并没有回答我的问题。 当我查看Laravel/Framework上的
我在玩 F# 句法。 在瑞典,我们有一个游戏叫做“Backslang”(谷歌翻译自“Rövarspråk”) 规则很简单。你说的所有话都必须以特定的方式说出来。虽然人声是相同的,但每个辅音都必须用“o
是否可以在Atom或Sublime Text中对“item”一词使用“查找和替换”并将其替换为“item [i]”,其中[i]是从1开始的数字? 我有一堆看起来像这样的物品: item1 item1
我不太确定如何解释,所以我将从输出开始。我需要返回这个: { replies: [ { type: 'text', content: 'one' } { type:
我是 C# 的新手,所以请原谅我的错误。 我想在每次调用该段代码时(每次调用 2-4 次)替换字符串的某些部分。我想知道哪种方法在性能方面更好:string.Replace 或 stringBuild
我了解.Replace() 和-replace 之间的区别,但是什么是-replace 和[Regex]: :替换()? 我测试了以下 2 个代码,但对我来说结果完全一样。 我还引用了 PowerSh
如果我正在做类似的事情: someString.Replace("abc","").Replace("def","").Replace(@"c:\Windows","") 我怎样才能把它替换成 Reg
我是 C# 的新手,所以请原谅我的错误。 我想在每次调用该段代码时(每次调用 2-4 次)替换字符串的某些部分。我想知道哪种方法在性能方面更好:string.Replace 或 stringBuild
当我使用 call() 或 apply() 时,我遇到了问题。 console.log(String.prototype.replace === String.replace);//false 我认为
在我使用 5-10 个替换的情况下是否有必要使用 stringbuilder。 String someData = "......"; someData = someData.replaceAll("
我有一个字符串,我需要用字典中的值替换其中的标记。它必须尽可能高效。使用 string.replace 进行循环只会消耗内存(记住,字符串是不可变的)。 StringBuilder.Replace()
我正在使用具有许多不同库依赖项的 gradle 项目并使用新的 list 合并。在我的 标签我已经这样设置了: .... 但我收到错误消息: /android/MyApp/app/src/main
我正在尝试从一个数据库中的表中提取模式并将其传输到另一个数据库。以下是执行此操作的函数的一部分。 当 Table( ... ) 时出错被称为。 功能示例: def transfer_data(self
我是一名优秀的程序员,十分优秀!