158 Stimmen

Wie kann ich den Text eines Elements ändern, ohne seine untergeordneten Elemente zu ändern?

Ich möchte den Text des Elements dynamisch aktualisieren:

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

Ich bin neu in jQuery, so dass diese Aufgabe scheint ziemlich schwierig für mich sein. Könnte jemand mich auf eine Funktion/Selektor zu verwenden zeigen?

Wenn es möglich ist, möchte ich dies tun, ohne einen neuen Container für den Text hinzuzufügen, den ich ändern muss.

104voto

Paul D. Waite Punkte 92952

Mark hat eine bessere Lösung mit jQuery aber vielleicht können Sie dies auch in normalem JavaScript tun.

In Javascript wird die childNodes gibt Ihnen alle untergeordneten Knoten eines Elements, einschließlich Textknoten.

Wenn Sie also wüssten, dass der Text, den Sie ändern wollen, immer der erste Teil des Elements sein wird, dann gäbe es z.B. dieses HTML:

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

Sie könnten dies tun:

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

var text_to_change = your_div.childNodes[0];

text_to_change.nodeValue = 'new text';

Natürlich können Sie auch jQuery verwenden, um die <div> in erster Linie (d. h. var your_div = $('your_div').get(0); ).

74voto

Mark Baijens Punkte 12586

Update 2018

Da dies eine ziemlich beliebte Antwort ist, habe ich beschlossen, sie zu aktualisieren und ein wenig zu verschönern, indem ich den Textnode-Selektor als Plugin zu jQuery hinzufüge.

In dem Schnipsel unten können Sie sehen, dass ich eine neue jQuery-Funktion, die alle (und nur) die textNodes bekommt definieren. Sie können diese Funktion auch verketten, zum Beispiel mit der first() Funktion. Ich beschneide den Textknoten und prüfe, ob er nach dem Beschneiden nicht leer ist, da Leerzeichen, Tabulatoren, neue Zeilen usw. ebenfalls als Textknoten erkannt werden. Wenn Sie diese Knoten auch benötigen, entfernen Sie sie einfach aus der if-Anweisung in der jQuery-Funktion.

Ich habe ein Beispiel hinzugefügt, wie man den ersten Textknoten ersetzt und wie man alle Textknoten ersetzt.

Dieser Ansatz macht den Code leichter lesbar und erleichtert seine mehrfache Verwendung für unterschiedliche Zwecke.

El Update 2017 (adrach) sollte ebenfalls funktionieren, wenn Sie dies bevorzugen.

Als jQuery-Erweiterung

//Add a jQuery extension so it can be used on any jQuery object
jQuery.fn.textNodes = function() {
  return this.contents().filter(function() {
    return (this.nodeType === Node.TEXT_NODE && this.nodeValue.trim() !== "");
  });
}

//Use the jQuery extension
$(document).ready(function(){
  $('#replaceAll').on('click', () => {
    $('#testSubject').textNodes().replaceWith('Replaced');
  });

  $('#replaceFirst').on('click', () => {
    $('#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>

Javascript (ES) eqivilant

//Add a new function to the HTMLElement object so it cna be used on any HTMLElement
HTMLElement.prototype.textNodes = function() {
  return [...this.childNodes].filter((node) => {
    return (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() !== "");
  });
}

//Use the new HTMLElement function
document.addEventListener('DOMContentLoaded', () => {
  document.querySelector('#replaceAll').addEventListener('click', () => {
    document.querySelector('#testSubject').textNodes().forEach((node) => {
      node.textContent = 'Replaced';
    });
  });

  document.querySelector('#replaceFirst').addEventListener('click', function() {
    document.querySelector('#testSubject').textNodes()[0].textContent = '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):

Es sieht so aus, als hätten sich seit der Veröffentlichung dieses Artikels einige Dinge geändert. Hier ist eine aktualisierte Version

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

Ursprüngliche Antwort (funktioniert nicht für aktuelle Versionen)

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

出典 http://api.jquery.com/contents/

58voto

In Aktion sehen

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

13voto

MrBojangles Punkte 1381

Fügen Sie den zu ändernden Text einfach in einen Span mit einer auszuwählenden Klasse ein.

Ich weiß, dass dies nicht unbedingt eine Antwort auf Ihre Frage ist, aber es ist wahrscheinlich eine bessere Kodierungspraxis. Halten Sie die Dinge sauber und einfach

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

12voto

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

Dies ändert nur den ersten Textknoten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X