文本节点我有一个小的文本节点:插入HTML与JavaScript的
var node
而且我想环绕的“笑”每一次出现的跨度。
node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>")
它它打印出"<span>lol<span>"
当我想"lol"
作为一个span元素。
文本节点我有一个小的文本节点:插入HTML与JavaScript的
var node
而且我想环绕的“笑”每一次出现的跨度。
node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>")
它它打印出"<span>lol<span>"
当我想"lol"
作为一个span元素。
您可能需要node
是父节点,这样你可以使用innerHTML:
node.innerHTML=node.childNodes[0].nodeValue.replace(/lol/, "<span>lol</span>");
这里node.childNodes[0]
指的是实际文本节点,node
是它包含的元素。
下面的文章给你的代码与HTML元素替换文本:
http://blog.alexanderdickson.com/javascript-replacing-text
从文章:
var matchText = function(node, regex, callback, excludeElements) {
excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
var child = node.firstChild;
do {
switch (child.nodeType) {
case 1:
if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) {
continue;
}
matchText(child, regex, callback, excludeElements);
break;
case 3:
child.data.replace(regex, function(all) {
var args = [].slice.call(arguments),
offset = args[args.length - 2],
newTextNode = child.splitText(offset);
newTextNode.data = newTextNode.data.substr(all.length);
callback.apply(window, [child].concat(args));
child = newTextNode;
});
break;
}
} while (child = child.nextSibling);
return node;
}
用法:
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) {
var span = document.createElement("span");
span.className = "search-term";
span.textContent = match;
node.parentNode.insertBefore(span, node.nextSibling);
});
而且解释:
从本质上讲,做正确的办法是...
- 遍历所有文本节点。
- 在文本节点中查找子字符串。
- 将它拆分为偏移量。
- 在分割之间插入一个span元素。
Andreas Josas提出的答案相当不错。但是,当搜索词出现在同一个文本节点中几次时,代码有几个错误。下面是修复了这些bug的解决方案,另外插入了matchText,以便于使用和理解。现在只有新的标记在回调中构造,并通过返回传递给matchText。
更新matchText功能与错误修正:
var matchText = function(node, regex, callback, excludeElements) {
excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
var child = node.firstChild;
while (child) {
switch (child.nodeType) {
case 1:
if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
break;
matchText(child, regex, callback, excludeElements);
break;
case 3:
var bk = 0;
child.data.replace(regex, function(all) {
var args = [].slice.call(arguments),
offset = args[args.length - 2],
newTextNode = child.splitText(offset+bk), tag;
bk -= child.data.length + all.length;
newTextNode.data = newTextNode.data.substr(all.length);
tag = callback.apply(window, [child].concat(args));
child.parentNode.insertBefore(tag, newTextNode);
child = newTextNode;
});
regex.lastIndex = 0;
break;
}
child = child.nextSibling;
}
return node;
};
用法:
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) {
var span = document.createElement("span");
span.className = "search-term";
span.textContent = match;
return span;
});
如果您希望插入锚(链接)标签span标签来代替,改变创造元素是“一“而不是”span“,添加一行以将href属性添加到标签,并将”a“添加到excludeElements列表中,以便链接不会在链接内创建。
我添加了修复'regex.lastIndex = 0'来重新使用正则表达式。看到http://stackoverflow.com/questions/1520800/why-regexp-with-global-flag-in-javascript-give-wrong-results – Jeff
不是说这是一个更好的答案,但我张贴我所做的完整性。在我的情况中,我已经查找或确定了需要在特定#text节点中突出显示的文本的偏移量。这也阐明了这些步骤。
//node is a #text node, startIndex is the beginning location of the text to highlight, and endIndex is the index of the character just after the text to highlight
var parentNode = node.parentNode;
// break the node text into 3 parts: part1 - before the selected text, part2- the text to highlight, and part3 - the text after the highlight
var s = node.nodeValue;
// get the text before the highlight
var part1 = s.substring(0, startIndex);
// get the text that will be highlighted
var part2 = s.substring(startIndex, endIndex);
// get the part after the highlight
var part3 = s.substring(endIndex);
// replace the text node with the new nodes
var textNode = document.createTextNode(part1);
parentNode.replaceChild(textNode, node);
// create a span node and add it to the parent immediately after the first text node
var spanNode = document.createElement("span");
spanNode.className = "HighlightedText";
parentNode.insertBefore(spanNode, textNode.nextSibling);
// create a text node for the highlighted text and add it to the span node
textNode = document.createTextNode(part2);
spanNode.appendChild(textNode);
// create a text node for the text after the highlight and add it after the span node
textNode = document.createTextNode(part3);
parentNode.insertBefore(textNode, spanNode.nextSibling);
在这种情况下,你将不得不repace与HTML内容
谢谢你,这是我的最佳答案 – romuleald
? –
@ArunPJohny文本节点如何做呢 – alt
@ JacksonGariety - 您需要用新的DOM span元素和文本节点替换文本节点,或者修改其父元素的innerHTML属性。走了,发布你的尝试。 – RobG