我有这个:
$(".forum-threadview-post-text:contains(':P')").html(":P").replaceWith("<img src='http://website.com/images/emotes/tongue.png' />");
它应该采用':P'的任何实例并用表情符号图像替换它。但是,它会使用以下内容发布:P并用该图像替换整个帖子。我怎样才能只替换:P。
答案 0 :(得分:4)
尝试
var tImg = "<img src='http://website.com/images/emotes/tongue.png' />";
$(".forum-threadview-post-text:contains(':P')").html(function (_, html) {
return html.replace(/:P/g , tImg )
});
<强> Demo 强>
您的原因无法按预期工作的原因是您要将匹配的元素替换为图像,而不是替换它的具体内容。您可以使用.html( function(index, oldhtml) )获取每个元素的html并替换它。
或者:
$(".forum-threadview-post-text:contains(':P')").contents().each(function () {
if(this.nodeType === 3 && /:P/g.test(this.nodeValue)) {
$(this).parent().html(this.nodeValue.replace(/:P/g,"<img src='http://placehold.it/10x10' />"));
}
});
答案 1 :(得分:2)
我认为最好不要假设文本将是传入选择器的直接子项。我还认为,您要搜索的文本不能出现在后代HTML标记中,这有点太明显了。到目前为止给出的所有其他答案至少在其中一个方面存在问题。
此外,使代码可重用更好。以下易于重复使用的函数将完全按照您的需要执行,不会被杂散的HTML标记属性弄乱,并且可以工作!
function descendantContents($el, textToFind) { // this could be made a jQuery plugin
var result = $el
.find(':not(script)')
.contents()
.filter(function () {
return this.nodeType === 3 && $(this).text().indexOf(textToFind) !== -1;
});
return result;
}
function replaceText(scopeSelector, textToFind, replacementHtml) {
descendantContents($(scopeSelector), textToFind)
.each(function () {
var element = $(this);
var parts = element.text().split(textToFind);
element.before(document.createTextNode(parts[0]));
for (var i = 1, l = parts.length; i < l; i += 1) {
element.before(replacementHtml);
element.before(document.createTextNode(parts[i]));
}
element.remove();
});
};
这些功能已在Firefox 25.0.1,Chrome 30.0.1599.101 m和10.0.9200.16721中使用jQuery 1.6.1进行了测试(我知道,这是一个旧版本,但这会让你感觉更好,而不是更糟)。
对于任何希望做得更好的人,请针对此HTML尝试您的代码:
<div>
<div>will this <span title="alt:Private">really</span> work :P</div>
</div>