我有以下简单的JQuery,它嵌入在我正在玩的项目的每个页面上:
$(document).ready(function(){
var replaced = $("body").html().replace(/$([a-zA-Z]+)b/g,
'<a href="https://finance.yahoo.com/quote/$1">$1</a>');
$("body").html(replaced);
});
正如你所看到的,如果它找到一个以$
开头的字符串,它就会假设提到了一个股票符号,并生成一个指向雅虎金融的链接。
问题是,作为生成内容过程的一部分,用户创建了他们的帖子,然后转到一个验证页面,该页面既呈现了他们的文章,又为他们的输入预先填充了字段,这样他们就可以进行编辑。这就是替换失败的地方,它在输入字段中生成HTML标记,导致它们过早关闭,基本上破坏了一切!
我几乎不熟悉任何Javascript(我的项目是Laravel 8项目,因为我想了解更多关于它的信息,碰巧我需要这部分作为前端(。
如何让Jquery执行文本替换,但不使用输入框?
这是页面加载并运行脚本后的粘贴。您可以在第25页看到,由于输入中的HTML代码被替换,输入被破坏:
https://pastebin.com/xGqKZXfT
我以前从未使用过本机TreeWalker API,但它非常适合您的需求。
我建议您不要针对任何包含脚本标记的容器,并且仍在寻找最佳的过滤方法。
以下内容并不完美,但它只修改文本节点,并在适用时将其替换为<span>
,以便允许<a>
进入。我可能会修改调整,但你可以用它来启动
$('.widget p').click(e=> alert('still works'))
const stockReg = /$([a-zA-Z]+)b/g;
const root = document.querySelector('#content')
const treeWalker = document.createTreeWalker(
root,
NodeFilter.SHOW_TEXT, {
acceptNode: function(node) {
return node.nodeValue.trim().length ? 1 : 2
// NodeFilter.FILTER_ACCEPT == 1;
// NodeFilter.FILTER_REJECT == 2;
}
},
false
);
const nodeList = [];
let currentNode = treeWalker.currentNode;
while (currentNode) {
nodeList.push(currentNode);
currentNode = treeWalker.nextNode();
}
nodeList.filter(n => n.nodeType === 3).forEach(n => {
// console.log('n.nodeTyp', n.nodeType, ' ', n.nodeName)
const txt = n.nodeValue;
if (txt && txt.match(stockReg)) {
const $span = $('<span>');
const html = txt.replace(stockReg, '<a href="https://finance.yahoo.com/quote/$1">$1</a>')
$span.html(html);
$(n).replaceWith($span);
}
})
console.log($('#content')[0].outerHTML)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div class="widget">I bought $AAPL
<p>After I sold $AMD and <span>some $GME</span>
</p>
</div>
</div>