我正在使用一个简单的浏览器插件来替换另一个单词,但添加了一个小工具提示/弹出的锚点。我已经实际使用了这个,但我的问题是,如果要替换的单词已经在锚点内,那么我的</a>
会关闭已经打开的<a>
。
所以我需要一些帮助,如何只替换一个单词,只要它不在一个开放的锚标签内。对此进行跟进也是为了确保目标词不在<input>
或其他不适当的标签中。
我的代码是:
var regex = new RegExp("\\b" + nativeWord + "\\b", "igm");
var body = $('body');
body.each(function() {
$(this).html(
$(this).html().replace(regex, function() {
counter++;
if(counter > wordSwapLimit) {
return nativeWord;
} else {
return "<a class=\"tooltip\" href=\"#\">" + studyWord + "<span class=\"classic\">" + nativeWord + "</span></a>";
}
})
);
});
我怀疑我可能需要编写一个更复杂的RegExp,但这是我第一次参加,所以任何建议都会非常感激!
更新 所以我有一个测试页面,我可以看看我的代码是如何工作的。 这是页面中原始HTML的一部分:
<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p>
但是使用上面显示的代码并将'chicken'换成'kip',这会改为:
<p id="changeArea"> I <a href="http://www.<a class=" tooltip"="">kip<span class="classic">chicken</span></a>.com">love <a class="tooltip" href="#">kip<span class="classic">chicken</span></a> but I hate beef. </p>
如果我在交换的内容周围没有任何锚点,那么它的工作原理非常好,我会得到一个很好的翻转工具提示。
再次感谢您的帮助!
更新2 根据要求,这里是'未经处理'的例子,我的插件可能在交换'kip'的'chicken'时遇到:
<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p>
<p id="changeArea2"> Chickenpie? pie-chicken. </p>
我希望的是以下内容:
<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p>
<p id="changeArea2"> Chickenpie? pie-<a class="tooltip" href="#">kip<span class="classic">chicken</span></a>. </p>
正如你在第一行中看到的那样,html代码是单独存在的,就像单词的文本一样,因为它在URL中,因此如果放入我的工具提示锚,它会破坏它。 第二行忽略了'chickenpie',因为根据我现有的正则表达式,我只想要整个单词交换。 “馅饼鸡”确实会被换掉。使用现有代码正确处理此行。
我真的只是想在我现有的代码中添加额外的规则,这些规则说'不要替换代码,如果在锚开放标记内,则不要替换。
答案 0 :(得分:0)
由于您使用的是JavaScript,因此您已经可以访问DOM。你为什么要试试using Regexes ???
只需遍历文本节点,忽略现有链接:
(function(elem) {
var recurse = arguments.callee, nodes = elem.childNodes, l = nodes.length, i, t,
getLink = function() {
var a = document.createElement('a'), s = document.createElement('span');
a.href = "#";
a.className = "tooltip";
a.appendChild(document.createTextNode(studyWord));
s.className = "classic";
s.appendChild(document.createTextNode(nativeWord));
a.appendChild(s);
return a;
};
for( i=0; i<l; i++) {
switch(nodes[i].nodeType) {
case 1:
// element - recurse, but not if already a link
if( nodes[i].nodeName != "A") recurse(nodes[i]);
break;
case 3:
// text node, look for keyword
t = nodes[i].nodeValue.search(new RegExp("\\b"+nativeWord+"\\b","i"));
if( t > -1) {
// found it! now to hack around...
t = nodes[i].splitText(t);
t.splitText(nativeWord.length);
t.parentNode.replaceChild(t,getLink());
}
break;
}
}
})(document.body);
请注意:此方法使用Vanilla JS。您可以确保在加载页面后运行。这可以通过以下方式完成:
defer
属性添加到脚本中(如果它是外部的)</body>
之前(或至少在您希望影响的所有内容之后)window.onload
处理程序中,甚至包含$(function() {...})
,因为您已经在使用jQuery。