我正在迭代html文档中的所有文本节点,以便围绕一些具有特定范围的单词。
更改nodeValue
不允许我插入html。转义span
以纯文本显示,我不希望这样。
这是我到目前为止所做的:
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 === Node.TEXT_NODE) {
node.nodeValue = node.nodeValue.replace(/Questions/, "<span>Questions</span>");
}
}
}
<p>Questions1</p>
<p>Questions 2</p>
<p>Questions 3</p>
<p>Questions 4</p>
答案 0 :(得分:3)
我认为你需要递归所有DOM和每场比赛...看看这里:
function replacer(node, parent) {
var r = /Questions/g;
var result = r.exec(node.nodeValue);
if(!result) { return; }
var newNode = this.createElement('span');
newNode.innerHTML = node
.nodeValue
.replace(r, '<span class="replaced">$&</span>')
;
parent.replaceChild(newNode, node);
}
document.addEventListener('DOMContentLoaded', () => {
function textNodesIterator(e, cb) {
if (e.childNodes.length) {
return Array
.prototype
.forEach
.call(e.childNodes, i => textNodesIterator(i, cb))
;
}
if (e.nodeType == Node.TEXT_NODE && e.nodeValue) {
cb.call(document, e, e.parentNode);
}
}
document
.getElementById('highlight')
.onclick = () => textNodesIterator(
document.body, replacer
);
});
&#13;
.replaced {background: yellow; }
.replaced .replaced {background: lightseagreen; }
.replaced .replaced .replaced {background: lightcoral; }
&#13;
<button id="highlight">Highlight</button>
<hr>
<p>Questions1</p>
<p>Questions 2</p>
<p>Questions 3</p>
<p>Questions 4</p>
<p>Questions 5 Questions 6</p>
<div>
<h1>Nesting</h1>
Questions <strong>Questions 4</strong>
<div> Questions <strong>Questions 4</strong></div>
<div>
Questions <strong>Questions 4</strong>
<div> Questions <strong>Questions 4</strong></div>
</div>
</div>
&#13;
答案 1 :(得分:1)
最后,我可以在不添加额外标记的情况下执行此操作,但需要的范围除外:
<强>更新强>
var elements = document.body.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],
par = node.parentElement;
// as well as checking the nodeType as text, we make sure the
// parent element doesn't have the class "foo", so that we only
// wrap the keyword once, instead of being in a loop to infinity
if (node.nodeType === Node.TEXT_NODE && !par.classList.contains('foo')) {
updateText(node, par);
}
}
}
function updateText(el, par) {
var nv = el.nodeValue,
txt = nv.replace(/Questions/g, '<span class="foo">Questions</span> ');
// replace the whole old text node with the new modified one
// and inject it as parent HTML
par.innerHTML = par.innerHTML.replace(nv, txt);
}
.foo {color: white; background-color: green; padding: 5px;}
<div id="wrapper">
this is test looking for the the word Questions.
<br>
<div id="test">
<p>Lorem ipsum dolor Questions sit amet, <strong>consectetur</strong> adipisicing elit.</p>
<p>Questions 1</p>
<p>Questions 2</p>
<p>Questions 3</p>
<p>Questions 4</p>
</div>
<div>Lorem ipsum dolor sit amet, Questions consectetur adipisicing elit. Ipsa sed Questions ratione dolorem at repellendus animi eveniet similique repellat, sequi rem numquam debitis sit reprehenderit laborum dicta omnis iure quidem atque?</div>
</div>
答案 2 :(得分:-2)
看到评论,不要使用它,因为它会严重搞乱页面。
保留后代,不要使用:
document.body.innerHTML = document.body.innerHTML.replaceAll(myVar, "<"+myTag+">"+myVar+</"+myTag+">");
有关https://stackoverflow.com/a/17606289/6660122和评论的更多信息。
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
document.body.innerHTML = document.body.innerHTML.replaceAll("Questions", "<b>Questions</b>");
<p>Questions1</p>
<p>Questions 2</p>
<p>Questions 3</p>
<p>Questions 4</p>
很好的学习案例!