409 Stimmen

Wie wähle ich Textknoten mit jQuery aus?

Ich möchte alle absteigenden Textknoten eines Elements als jQuery-Sammlung erhalten. Was ist der beste Weg, das zu tun?

276voto

Tim Down Punkte 304837

JQuery verfügt nicht über eine praktische Funktion für diese Aufgabe. Sie müssen Folgendes kombinieren contents() , die nur untergeordnete Knoten, aber auch Textknoten enthält, mit find() , die alle nachgeordneten Elemente, aber keine Textknoten enthält. Hier ist, was ich habe mit kommen:

var getTextNodesIn = function(el) {
    return $(el).find(":not(iframe)").addBack().contents().filter(function() {
        return this.nodeType == 3;
    });
};

getTextNodesIn(el);

Hinweis: Wenn Sie jQuery 1.7 oder früher verwenden, wird der obige Code nicht funktionieren. Um dies zu beheben, ersetzen Sie addBack() con andSelf() . andSelf() ist veraltet zu Gunsten von addBack() ab 1.8.

Dies ist im Vergleich zu reinen DOM-Methoden etwas ineffizient und muss eine hässliche Umgehung für jQuery's Überladung der contents() Funktion (Dank an @rabidsnail in den Kommentaren für den Hinweis, dass aus), so ist hier nicht jQuery Lösung mit einer einfachen rekursiven Funktion. Die includeWhitespaceNodes steuert, ob Textknoten mit Leerzeichen in der Ausgabe enthalten sind oder nicht (in jQuery werden sie automatisch herausgefiltert).

Aktualisieren: Fehler behoben, wenn includeWhitespaceNodes fehlerhaft ist.

function getTextNodesIn(node, includeWhitespaceNodes) {
    var textNodes = [], nonWhitespaceMatcher = /\S/;

    function getTextNodes(node) {
        if (node.nodeType == 3) {
            if (includeWhitespaceNodes || nonWhitespaceMatcher.test(node.nodeValue)) {
                textNodes.push(node);
            }
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                getTextNodes(node.childNodes[i]);
            }
        }
    }

    getTextNodes(node);
    return textNodes;
}

getTextNodesIn(el);

222voto

Christian Oudard Punkte 45045

Jauco hat eine gute Lösung in einem Kommentar gepostet, deshalb kopiere ich sie hier:

$(elem)
  .contents()
  .filter(function() {
    return this.nodeType === 3; //Node.TEXT_NODE
  });

20voto

He Nrik Punkte 1641
$('body').find('*').contents().filter(function () { return this.nodeType === 3; });

8voto

Salman A Punkte 246207

jQuery.contents() kann verwendet werden mit jQuery.filter um alle untergeordneten Textknoten zu finden. Mit einem kleinen Trick können Sie auch Textknoten von Enkeln finden. Keine Rekursion erforderlich:

$(function() {
  var $textNodes = $("#test, #test *").contents().filter(function() {
    return this.nodeType === Node.TEXT_NODE;
  });
  /*
   * for testing
   */
  $textNodes.each(function() {
    console.log(this);
  });
});

div { margin-left: 1em; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="test">
  child text 1<br>
  child text 2
  <div>
    grandchild text 1
    <div>grand-grandchild text 1</div>
    grandchild text 2
  </div>
  child text 3<br>
  child text 4
</div>

jsFiddle

4voto

Alex W Punkte 34972

Mit der akzeptierten Filterfunktion erhielt ich eine Menge leerer Textknoten. Wenn Sie nur an der Auswahl von Textknoten interessiert sind, die keine Leerzeichen enthalten, fügen Sie eine nodeValue Bedingung für Ihre filter Funktion, wie eine einfache $.trim(this.nodevalue) !== '' :

$('element')
    .contents()
    .filter(function(){
        return this.nodeType === 3 && $.trim(this.nodeValue) !== '';
    });

http://jsfiddle.net/ptp6m97v/

Oder um seltsame Situationen zu vermeiden, in denen der Inhalt wie ein Leerzeichen aussieht, es aber nicht ist (z. B. der weiche Bindestrich &shy; Zeichen, Zeilenumbrüche \n , Tabulatoren usw.), können Sie versuchen, einen regulären Ausdruck zu verwenden. Zum Beispiel, \S passt auf alle Zeichen, die keine Leerzeichen sind:

$('element')
        .contents()
        .filter(function(){
            return this.nodeType === 3 && /\S/.test(this.nodeValue);
        });

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