我被引导到GitHub上的Linkify项目(https://github.com/cowboy/javascript-linkify)寻找和"linkifying"url和域名只是在文本中浮动。
这是太棒了!它完全适用于文本!
然而,我不太确定如何使它在textNode
上工作,其中有我想要链接的文本。
我理解textNode
只有textContent
,因为……都是文字。既然这个Linkify函数返回HTML作为文本,是否有一种方法来获取textNode并"重写"?其中的HTML与Linkify输出?
我一直在JSFiddle上玩它:http://jsfiddle.net/AMhRK/9/
function repl(node) {
var nodes = node.childNodes;
for (var i = 0, m = nodes.length; i < m; i++) {
var n = nodes[i];
if (n.nodeType == n.TEXT_NODE) {
// do some swappy text to html here?
n.textContent = linkify(n.textContent);
} else {
repl(n);
}
}
}
您需要将textNode替换为一个HTML元素,比如span,然后将您的链接文本设置为该元素的innerHTML。
var replacementNode = document.createElement('span');
replacementNode.innerHTML = linkify(n.textContent);
n.parentNode.insertBefore(replacementNode, n);
n.parentNode.removeChild(n);
除了前面的答案,我还提出了更短的方法(基于jQuery):
$(n).replaceWith('Some text with <b>html</b> support');
其中n
-为textNode。
或者本地版本
var txt = document.createElement("span");
txt.innerHTML = "Some text with <b>html</b> support";
node.replaceWith(txt);
其中node
为textNode
基于@AlexJeffcott的回答:使用DocumentFragment而不是乱用<span>
, innerHTML和childNodes的Perf优化版本😁
const enhanceNodes = (textNodes) => {
textNodes.forEach((node) => {
const oldText = node.textContent;
const newText = fancyTextTranformation(oldText);
const fragment = document.createRange().createContextualFragment(newText);
node.replaceWith(fragment);
})
}
以Will Scott的回答为基础,如果您不希望在span中包装所有内容,您可以这样做:
const enhanceNodes = (textNodes) => {
const renderNode = document.createElement('span');
textNodes.forEach((node) => {
const oldText = node.textContent;
renderNode.innerHTML = fancyTextTranformation(oldText);
node.replaceWith(...renderNode.childNodes);
})
}