JQuery更改内部文本但保留HTML

76
我想使用jQuery更改HTML元素中的文本,但保留其余内部HTML的内容。
例如:
<a href="link.html">Some text <img src="image.jpg" /></a> 

将"一些文本"替换为"其他文本",结果应该如下:

<a href="link.html">Other text <img src="image.jpg" /></a> 

编辑: 我的当前解决方案如下:

var aElem = $('a');
var children = aElem.children();

aElem.text("NEW TEXT");
aElem.append(children); 

但一定有更优雅的方法来实现这个。


你想在哪个事件中改变值? - xkeshav
14个回答

40

这看起来完全正常。

演示

<html>
    <head>
    </head>
    <body>
        <a href="link.html">Some text <img src="img.jpg" /></a>
    </body>

    </html>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
    <script type="text/javascript">
        $(function(){
            var $link = $('a');
            var $img = $link.find('img'); 
            $link.html('New Text');
            $link.append($img);
        });
    </script>

4
是的,这与我的当前解决方案相似。我使用children()属性,然后重新将子元素插入到元素中。这个方法可以正常工作,但是我想知道是否有更好的解决方案。 - Drejc
您应该使用 $link.children('img') 而不是 find() 方法,因为您想要直接子元素。使用 find() 来搜索孙子元素。 - Eugen Zaharia
2
只要您没有将任何事件监听器绑定到<a>标签内部的HTML上,这个解决方案就可以正常工作。否则,您将不得不再次添加这些监听器。 - Pedro Hoehl Carvalho

37

由于您无法修改链接,一个选择是简单地使用replace

$("a").html($("a").html().replace("Some text", "Other text"));

jsfiddle上的示例。


3
为什么会有人点踩?使用这种方法可以保留原始的标记。例如,对于 <a><img/>一些文本<img/></a> ,使用分离/重新连接的方法会导致结果变成 <a>其他文本<img/><img/></a> ,而使用简单替换会保持结构不变。 - Mark Coleman
4
如果 <img> 标签中包含了 Some text,那会怎样? - Philippe Lavoie
我不知道为什么会给你的回答点踩,可能是我的失误。 刚看到我的分数上升了9分,但是发现少了一分,后来发现是在这里点踩了。 除非回答被编辑过,否则我无法取消点踩 :/ - max-m
4
有点天真了吧?我投反对票,因为显然在部署时要替换的字符串“Some text”不会是唯一要被替换的。在动态网站中肯定会有其他字符串需要替换,所以不能依赖这种字符串匹配的方法。 - Niklas Wulff
可以通过缓存jQuery选择来改进。 - anthonygore
此外,这仅替换第一次出现。如果您想要替换多次,则可以使用RegExp - CodeBrauer

23

将您想要更改的文本包装在标记内

<a href="link.html"><span>Some text</span> <img src="image.jpg" /></a> 

$('a span').html( 'new text' );

3
无法这样做,因为这些元素是从其他来源动态生成的。 - Drejc
3
然而,对于大多数人来说,这是最好的答案。 - dlsso

14

我的解决方案虽然有点晚.

$('a').each(function() {
    var contents = $(this).contents();
    if (contents.length > 0) {
        if (contents.get(0).nodeType == Node.TEXT_NODE) {
            $(this).html('NEW TEXT').append(contents.slice(1));
        }
    }
});

注意事项:

  1. contents() 包含文本节点,而 children() 不包含。
  2. 必须通过 var contents = ... 创建一个内容的副本,否则一旦用 $(this).html('NEW TEXT') 替换剩余元素,它们就会永远丢失。
  3. length 检查是可选的但建议使用。
  4. nodeType 检查是可选的但建议使用。

2
这似乎是最理想的方法。这也可以工作: $(this).contents()。filter(function(){ 返回this.nodeType == 3; })。each(function(){this.nodeValue =“whatever”; }) - electrichead
这是否保留了绑定到子元素的事件? - Sanjay Manohar
它不起作用,因为它会影响innerHTML属性。请参考@jim_kastrin的答案以获取解决方案。 - Andrew Cheong

13

另一种方法是使用以下方式的contents()方法:

给定

<a href="link.html">Some text <img src="image.jpg" /></a>

你可以使用jQuery替换'Some text'

var text = $('a').contents().first()[0].textContent;
$('a').contents().first()[0].textContent = text.replace("Some text", "Other text");

这里有一个jsFiddle示例

contents()的想法来自用户charlietfl在这个问题中的回答。


3
这似乎是最完整的答案,因为绑定在子HTML节点上的任何事件监听器都不会受到更改的影响。 - Pedro Hoehl Carvalho
我仍然遇到了使用这种方法时出现的问题,但是Darryl Ceguerra的答案完美地解决了这个问题。 - Merlin04

12
你可以通过 .contents() 进行更改。
$('.yourElement').contents()[0].data = 'New Data';

在您的情况中,"[0].data" 是您的文本数据


2
最佳解决方案在这里,非常感谢!不会影响绑定到HTML的任何事件监听器。 - sandy
与jQuery DataTables完美配合。 - Joseph Wambura

2

只需使用一些普通的js功能:

$('a')[0].firstChild.nodeValue = "新文本";


1
一种高效且稳健的方法,无需了解内部元素或文本内容:
var $a = $('a');
var inner = '';
$a.children.html().each(function() {
    inner = inner + this.outerHTML;
});
$a.html('New text' + inner);

1

尝试这段代码

$('a').live('click', function(){
    var $img = $(this).find('img'); 
    $(this).text('changed');
    $(this).append($img);
});

这样做不起作用,因为它将替换整个内部部分,包括保持HTML元素。 - Drejc

0
你需要添加一个 <span> 元素并更改该元素的文本,例如:
<a href="link.html"><span id="foo">Some text</span><img src="image.jpg" /></a>

然后,您可以从 jQuery 中调用:

$("#foo").html("Other text");

你的结果将会有效地是:

<a href="link.html"><span id="foo">Other text</span><img src="image.jpg" /></a>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接