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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4106809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 10:38:08  来源:igfitidea点击:

How can I change an element's text without changing its child elements?

javascriptjquery

提问by ika

I'd like to update element's text dynamically:

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

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

I'm new to jQuery, so this task seems to be quite challenging for me. Could someone point me to a function/selector to use?

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

If it is possible, I'd like to do it without adding a new container for the text I need to change.

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

采纳答案by Paul D. Waite

Mark's got a better solution using jQuery, but you might be able to do this in regular JavaScript too.

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

In Javascript, the childNodesproperty gives you all the child nodes of an element, including text nodes.

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

So, if you knew the text you wanted to change was always going to be the first thing in the element, then given e.g. this HTML:

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

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

You could do this:

你可以这样做:

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

var text_to_change = your_div.childNodes[0];

text_to_change.nodeValue = 'new text';

Of course, you can still use jQuery to select the <div>in the first place (i.e. var your_div = $('your_div').get(0);).

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

回答by Mark Baijens

Update 2018

2018 年更新

Since this is a pretty popular answer I decided to update and beautify it a little by adding the textnode selector to jQuery as a plugin.

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

In the snippet below you can see that I define a new jQuery function that gets all (and only) the textNodes. You can chain of this function as well with for example the first()function. I do a trim on the text node and check if it's not empty after the trim because spaces, tabs, new lines, etc. are also recognized as text nodes. If you need those nodes too then simple remove that from the if statement in the jQuery function.

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

I added an example how to replace first text node and how to replace all text nodes.

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

This approach makes it easier to read the code and easier to use it multiple times and with different purposes.

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

The Update 2017 (adrach)should still work as well if you prefer that.

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

jQuery.fn.textNodes = function() {
  return this.contents().filter(function() {
    return (this.nodeType === Node.TEXT_NODE && this.nodeValue.trim() !== "");
  });
}

$(document).ready(function(){
  $('#replaceAll').on('click', function() {
    $('#testSubject').textNodes().replaceWith('Replaced');
  });

  $('#replaceFirst').on('click', function() {
    $('#testSubject').textNodes().first().replaceWith('Replaced First');
  });
});
p {
  margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
   **text to change**
   <p>text that should not change</p>
   <p>text that should not change</p>
   **also text to change**
   <p>text that should not change</p>
   <p>text that should not change</p>
   **last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>



Update 2017 (adrach):

2017 年更新(adrach):

It looks like several things changed since this was posted. Here is an updated version

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

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


Original answer (Not working for current versions)

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

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

Source: http://api.jquery.com/contents/

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

回答by Mark Baijens

See In action

见行动

Markup :

标记:

$(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" />

回答by ilkin

<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");
});

This changes only the first textnode

这仅更改第一个文本节点

回答by MrBojangles

Just wrap the text you want to change in a span with a class to select.

只需将要更改的文本用一个类包裹起来即可选择。

Doesn't necessarily answer your question I know, but, probably a better coding practice. Keep things clean and simple

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

<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>

Voilà!

瞧!

$('#header .mytext').text('New text here')

回答by Tim Down

For the specific case you mentioned:

对于您提到的具体情况:

<div id="foo">
   **text to change**
   <someChild>
       text that should not change
   </someChild>
   <someChild>
       text that should not change
   </someChild>
</div>

... this is very easy:

...这很容易:

var div = document.getElementById("foo");
div.firstChild.data = "New text";

You don't state how you want to generalize this. If, say, you want to change the text of the first text node within the <div>, you could do something like this:

你没有说明你想如何概括这一点。例如,如果您想更改 中第一个文本节点的文本<div>,您可以执行以下操作:

var child = div.firstChild;
while (child) {
    if (child.nodeType == 3) {
        child.data = "New text";
        break;
    }
    child = child.nextSibling;
}

回答by geg

$.fn.textPreserveChildren = function(text) {
  return this.each(function() {
    return $(this).contents().filter(function() {
      return this.nodeType == 3;
    }).first().replaceWith(text);
  })
}

setTimeout(function() {
  $('.target').textPreserveChildren('Modified');
}, 2000);
.blue {
  background: #77f;
}
.green {
  background: #7f7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<div class="target blue">Outer text
  <div>Nested element</div>
</div>

<div class="target green">Another outer text
  <div>Another nested element</div>
</div>

回答by user1254723

Lots of great answers here but they only handle one text node with children. In my case I needed to operate on all text nodes and ignore html children BUT PRESERVE THE ORDERING.

这里有很多很棒的答案,但它们只处理一个带有孩子的文本节点。在我的情况下,我需要对所有文本节点进行操作并忽略 html 子节点,但保留顺序。

So if we have a case like this:

所以如果我们有这样的案例:

<div id="parent"> Some text
    <div>Child1</div>
    <div>Child2</div>
    and some other text
    <div>Child3</div>
    <div>Child4</div>
    and here we are again
</div>

We can use the following code to modify the text only AND PRESERVE THE ORDERING

我们可以使用以下代码仅修改文本并保留顺序

    $('#parent').contents().filter(function() {
        return this.nodeType == Node.TEXT_NODE && this.nodeValue.trim() != '';
    }).each(function() {
      //You can ignore the span class info I added for my particular application.
        $(this).replaceWith(this.nodeValue.replace(/(\w+)/g,"<span class='IIIclassIII' onclick='_mc(this)' onmouseover='_mr(this);' onmouseout='_mt(this);'>X</span>"));
 });
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<div id="parent"> Some text
    <div>Child1</div>
    <div>Child2</div>
    and some other text
    <div>Child3</div>
    <div>Child4</div>
    and here we are again
</div>

Here is the jsfiddleof it working

这是它工作的jsfiddle

回答by Silver Ringvee

2019 vesrsion - Short & Simple

2019 版 - 简短而简单

document.querySelector('#your-div-id').childNodes[0].nodeValue = 'new text';

Explanation

解释

document.querySelector('#your-div-id')is used for selecting the parent (the element which text you are about to change)

document.querySelector('#your-div-id')用于选择父元素(您将要更改的文本元素)

.childNodes[0]selects the text node

.childNodes[0]选择文本节点

.nodeValue = 'new text'sets text node value to "new text"

.nodeValue = 'new text'将文本节点值设置为“新文本”



This answer is possibly inspired by Dean Martin's comment. Can't say for sure since I've been using this solution for years now. Just thought I should post this probability here because some people care about it more than the fact that this is the best solution.

这个答案可能受到 Dean Martin 评论的启发。不能肯定,因为我多年来一直在使用这个解决方案。只是想我应该在这里发布这个概率,因为有些人更关心它而不是这是最好的解决方案。

回答by Yasser Shaikh

Here is yetanother method : http://jsfiddle.net/qYUBp/7/

这是一种方法:http://jsfiddle.net/qYUBp/7/

HTML

HTML

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

JQUERY

查询

var tmp=$("#header>div").html();
$("#header").text("its thursday").append(tmp);