子要素を変更せずに要素のテキストを変更するにはどうすればよいですか?


120

要素のテキストを動的に更新したい:

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

私はjQueryを初めて使用するので、このタスクは私にとって非常に難しいようです。誰かが使用する関数/セレクターを教えてもらえますか?

可能であれば、変更する必要のあるテキスト用の新しいコンテナーを追加せずにそれを実行したいと思います。


7
「可能であれば、変更する必要のあるテキスト用の新しいコンテナーを追加せずにそれを実行したいと思います。」- 本当に?そこにコンテナがあればはるかに簡単になるからです。
ポールD.ウェイト

... Guysは、私は元の質問を見て、私はOPは、子要素については何も言っていることはないと思う
サイムVIDAS

W3標準によると、divにはテキストノードさえありません(私が正しいことを覚えている場合)。<p>、<h1>などのテキストコンテナを追加する必要があります。
Mark Ba​​ijens、2010年

2
@Mark:(X)HTML Strictの可能性がありますが、それ以上はありません。(HTML5は現在ここにあります。)
ポールD.ウェイト2010年

@マットボール:実際のhtmlには、someChildの代わりにspanタグがあります。
ika

回答:


75

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);)を選択することもできます。


1
テキストノードを置き換える必要はありません。既存のものdataまたはnodeValueプロパティを変更するだけです。
Tim Down

@ティム:ああ、もっと簡単な方法があるに違いないと思った。jQueryが登場するまで、JavaScriptをあまり実行していませんでした。乾杯、私はそれに応じて答えを編集します。
ポールD.ウェイト

11
したがって、この回答のより最新の実装は次のようになります$('#yourDivId')[0].childNodes[0].nodeValue = 'New Text';
Dean Martin

最短と最も簡単な解決策は、はるかに- stackoverflow.com/a/54365288/4769218
シルバーRingvee

1
「通常のJavaScriptでもこれを実行できる場合があります」
duhaime

65

2018年の更新

これは非常に人気のある回答なので、プラグインとしてjQueryにtextnodeセレクターを追加することで、少し更新して美化することにしました。

以下のスニペットでは、すべての(そして唯一の)textNodeを取得する新しいjQuery関数を定義していることがわかります。この関数は、たとえば関数と連鎖させることもできfirst()ます。スペース、タブ、改行などもテキストノードとして認識されるため、テキストノードでトリミングを行い、トリミング後に空でないことを確認します。それらのノードも必要な場合は、jQuery関数のifステートメントから単純に削除します。

最初のテキストノードを置き換える方法とすべてのテキストノードを置き換える方法の例を追加しました。

このアプローチにより、コードが読みやすくなり、コードを複数回、さまざまな目的で使用しやすくなります。

必要に応じてUpdate 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/


ああ!どこかに賢いjQuery関数があることは知っていました。あなたが書いたときのソリューションの唯一の問題は、すべてのテキストノードが次のテキストを取得することです(たとえば、子要素内のテキストを含む)。それを制限するのはそれほど難しいことではないでしょうか?
ポールD.ウェイト2010年

10
の使用.filter(':first')に問題がありましたが、.first()代わりに使用することでうまくいきました。ありがとう!
hollaburoo

16
これは.text()このjsfiddleを参照)では機能しませんが、.replaceWith()jsfiddle here)では機能します。
magicalex

2
これは、textObject = $(myNode).contents()。filter(function(){return this.nodeType == 3;})[0] $(textObject).replaceWith( "my text"なので、醜く機能します。 );
Maragues 2012

nodeType=3それについて知りたい人は、「TEXT」のノードタイプのみをフィルターすることを意味します。詳細については、w3schools.com / jsref / prop_node_nodetype.asp
ktutnik

53

実際に見る

マークアップ:

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


6
私が出会った中でこれまでで最高のソリューション。エレガントでシンプル。
Yoav Kadosh 2013年

3
ただし、ノードの順序は保持されません。たとえば、テキストが最初に要素の終わりにあった場合、それは今、最初にあります。
マット

順序は保持されませんが、ほとんどの場合、テキストを最初または最後のノードとして使用します。したがって、append()が望ましい結果を得られない場合、既存の子をテキストの前に置きたい場合は、prepend()を試してください。
Sensei

はるかに短いと、最も簡単な解決策- stackoverflow.com/a/54365288/4769218
シルバーRingvee

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

これは最初のテキストノードのみを変更します


9

変更するテキストを、選択するクラスでスパンにラップするだけです。

私が知っているあなたの質問に必ずしも答えるとは限りませんが、おそらくより良いコーディングの実践です。物事をクリーンでシンプルに保つ

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

これが最善の解決策です!
Sleek Geek

5

あなたが言及した特定のケースについて:

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

...これはとても簡単です:

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

これをどのように一般化したいかは述べていません。たとえば、内の最初のテキストノードのテキストを変更する場合は、次の<div>ようにします。

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

2

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


1

ここにさらに別の方法があります:http : //jsfiddle.net/qYUBp/7/

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

1

ここにはたくさんの素晴らしい答えがありますが、それらは子供を持つ1つのテキストノードしか処理しません。私の場合、すべてのテキストノードを操作し、htmlの子を無視する必要がありますが、順序は保持します。

したがって、次のようなケースがある場合:

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

次のコードを使用して、テキストのみを変更し、順序を維持できます。

    $('#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$1' onclick='_mc(this)' onmouseover='_mr(this);' onmouseout='_mt(this);'>$1X</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>

これが動作しているjsfiddleです


0

.prependTo()を探していると思います。

http://api.jquery.com/prependTo/

ページ上の要素を選択して、別の要素に挿入することもできます。

$( 'h2')。prependTo($( '。container'));

この方法で選択された要素が別の場所に挿入された場合、その要素はターゲットに移動されます(クローンではありません)。

<div class="container">  
  <h2>Greetings</h2>
  <div class="inner">Hello</div>
  <div class="inner">Goodbye</div> 
</div>

ただし、複数のターゲット要素がある場合、挿入された要素の複製されたコピーは、最初の後に各ターゲットに対して作成されます。


2
私はそうは思いません。OPは新しいテキストを追加するのではなく、テキストを変更する方法を探しているようです。
マットボール

0

簡単な答え:

$("div").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0].nodeValue = "The text you want to replace with"

0

マークの答えの問題は、空のテキストノードも取得することです。jQueryプラグインとしてのソリューション:

$.fn.textnodes = function () {
    return this.contents().filter(function (i,n) {
        return n.nodeType == 3 && n.textContent.trim() !== "";
    });
};

$("div").textnodes()[0] = "changed text";

0

これは古い質問ですが、次のような単純な関数を作成して人生を楽にすることができます。

$.fn.toText = function(str) {
    var cache = this.children();
    this.text(str).append(cache);
}

例:

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

使用法:

$("#my-div").toText("helloworld");

0

2019バージョン-ショート&シンプル

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

説明

document.querySelector('#your-div-id') 親(変更しようとしているテキストの要素)を選択するために使用されます

.childNodes[0] テキストノードを選択します

.nodeValue = 'new text' テキストノードの値を「新しいテキスト」に設定します


この答えは、おそらくディーン・マーティンのコメントに触発されたものです。このソリューションを何年も使用しているので、はっきりとは言えません。一部の人々はこれが最善の解決策であるという事実よりもそれを気にしているので、私はこの確率をここに投稿するべきだと思いました。


2
Dean Martinのコメントを2014年からコピーし、2019年のソリューションとしてこれを主張しました。また、jQueryとプレーンJavascriptの不要な組み合わせを使用します。これは、私の見解では、読みやすさの点で悪い習慣です。最後に、ソリューションがどのように機能するかについての詳細は入力しませんでした。それは最も複雑ではありませんが、この問題もそうではないので、おそらくこれを読んだかなり新しいプログラマーであり、配列インデックスにアクセスしてjQueryオブジェクトからネイティブDOMノードを取得するなどの追加の説明を使用できます。
Mark Ba​​ijens、

@MarkBaijens私はあなたが正しいと思うかもしれません、ディーン・マーティンのコメントは私が何年も前にこのスニペットを得た場所かもしれません。とにかく、それ以来ずっとそれを使っており、1月に私の個人的なコードリポジトリ(便利なスクリプトをリストしている)からコピーしただけです。より詳細な説明を追加し、不要なjQueryを削除しました。
シルバーリングビー

これは実際に機能する最も単純なソリューションであり、人々はそれを使用する必要がありますが、ディーン・マーティンにクレジットを与えずに自分でそれをポーンすることに対する賞賛は得られません。また、この場合の純粋なバニラJS実装は、jQueryとバニラJSを混同するよりも優れているという点で、マークバイジェンスにも同意します。読みやすさだけでなく、jQueryの速度が低下するためパフォーマンスも向上します。
Miqi180

@ Miqi180-すでに上で述べたように、これは可能です。このソリューションを最初にどこで入手したか覚えていません。もう何年も仕事で使っています。回答にメモを追加しました。うまくいけば、それがSOのここでの最善の解決策を気にしないあなたのような人々を助けるでしょう:
Silver Ringvee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.