如何在不更改其子元素的情况下更改元素的文本?

IT技术 javascript html jquery
2021-01-29 22:56:41

我想动态更新元素的文本:

<div>
   **text to change**
   <someChild>
       text that should not change
   </someChild>
   <someChild>
       text that should not change
   </someChild>
</div>

我是 jQuery 的新手,所以这项任务对我来说似乎很有挑战性。有人可以指出我要使用的功能/选择器吗?

如果可能,我希望在不为需要更改的文本添加新容器的情况下执行此操作。

6个回答

Mark 使用 jQuery 获得了更好的解决方案,但您也可以在常规 JavaScript 中执行此操作。

在 Javascript 中,该childNodes属性为您提供元素的所有子节点,包括文本节点。

因此,如果您知道要更改的文本始终是元素中的第一件事,那么给定例如以下 HTML:

<div id="your_div">
   **text to change**
   <p>
       text that should not change
   </p>
   <p>
       text that should not change
   </p>
</div>

你可以这样做:

var your_div = document.getElementById('your_div');

var text_to_change = your_div.childNodes[0];

text_to_change.nodeValue = 'new text';

当然,您仍然可以首先使用 jQuery 来选择<div>(即var your_div = $('your_div').get(0);)。

无需替换文本节点。只需更改现有的datanodeValue属性即可。
2021-03-13 22:56:41
“您也可以在常规 javascript 中执行此操作”
2021-03-16 22:56:41
@Tim:啊,我想一定有更简单的方法。在 jQuery 出现之前,从来没有做过很多 JavaScript。干杯,我会相应地编辑答案。
2021-03-20 22:56:41
@duhaime 我打算添加类似的东西,但你的金子是我的男人!
2021-04-08 22:56:41
因此,此答案的更新实施将是 $('#yourDivId')[0].childNodes[0].nodeValue = 'New Text';
2021-04-09 22:56:41

2018 年更新

由于这是一个非常受欢迎的答案,我决定通过将 textnode 选择器作为插件添加到 jQuery 来更新和美化它。

在下面的代码片段中,您可以看到我定义了一个新的 jQuery 函数,该函数获取所有(且仅)textNode。您也可以将此函数与例如first()函数链接起来。我对文本节点进行修剪并检查修剪后它是否不为空,因为空格、制表符、新行等也被识别为文本节点。如果你也需要这些节点,那么简单地从 jQuery 函数的 if 语句中删除它。

我添加了一个示例,如何替换第一个文本节点以及如何替换所有文本节点。

这种方法使代码更易于阅读,并且更易于多次使用并用于不同目的。

更新2017年(adrach)如果你喜欢的应该仍然正常工作。

作为 jQuery 扩展

Javascript (ES) 等效


2017 年更新(adrach):

自发布以来,似乎有几件事发生了变化。这是一个更新的版本

$("div").contents().filter(function(){ return this.nodeType == 3; }).first().replaceWith("change text");

原始答案(不适用于当前版本)

$("div").contents().filter(function(){ return this.nodeType == 3; })
.filter(':first').text("change text");

来源:http : //api.jquery.com/contents/

这对我不起作用.text()(请参阅此 jsfiddle)但适用于.replaceWith()此处为 jsfiddle)。
2021-03-20 22:56:41
啊哈!我知道某个地方会有一个聪明的 jQuery 函数。您编写的解决方案的唯一问题是每个文本节点都会获取下一个文本(例如,包括子元素中的那些)。我想限制它不会太难吗?
2021-03-23 22:56:41
这对我有用,丑陋,因为它是 textObject = $(myNode).contents().filter(function(){ return this.nodeType == 3; })[0] $(textObject).replaceWith("my text" );
2021-04-01 22:56:41
我在使用时遇到了一些麻烦.filter(':first'),但使用.first()对我有用。谢谢!
2021-04-06 22:56:41
任何对此感到好奇的人nodeType=3都是仅过滤节点类型的“文本”,w3schools.com/jsref/prop_node_nodetype.asp了解更多信息
2021-04-06 22:56:41

见在行动

标记:

$(function() {
  $('input[type=button]').one('click', function() {
    var cache = $('#parent').children();
    $('#parent').text('Altered Text').append(cache);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">Some text
  <div>Child1</div>
  <div>Child2</div>
  <div>Child3</div>
  <div>Child4</div>
</div>
<input type="button" value="alter text" />

到目前为止,我遇到的最好的解决方案。优雅而简单。
2021-03-21 22:56:41
但是,这不会保留节点的顺序。例如,如果文本首先位于元素的末尾,则它现在位于元素的开头。
2021-03-22 22:56:41
它不会保留顺序,但在大多数情况下,您希望文本作为第一个或最后一个节点。所以如果 append() 没有得到想要的结果,如果你想要文本前面的现有子项,请尝试 prepend() 。
2021-03-22 22:56:41
迄今为止最短最简单的解决方案 - stackoverflow.com/a/54365288/4769218
2021-04-05 22:56:41

只需将要更改的文本包含在一个要选择的类中即可。

我知道不一定能回答你的问题,但是,可能是更好的编码实践。保持事物干净和简单

<div id="header">
   <span class="my-text">**text to change**</span>
   <div>
       text that should not change
   </div>
   <div>
       text that should not change
   </div>
</div>

瞧!

$('#header .mytext').text('New text here')
简单直接的解决方案。拯救了我的一天。
2021-03-30 22:56:41
这是最好的解决方案!
2021-04-07 22:56:41
<div id="divtochange">
    **text to change**
    <div>text that should not change</div>
    <div>text that should not change</div>
</div>
$(document).ready(function() {
    $("#divtochange").contents().filter(function() {
            return this.nodeType == 3;
        })
        .replaceWith("changed text");
});

这仅更改第一个文本节点