Frage JavaScript .querySelector findet
mit innerTEXT


Wie kann ich DIV mit einem bestimmten Text finden? Beispielsweise:

<div>
SomeText, text continues.
</div>

Versuche, etwas wie folgt zu verwenden:

var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);

Aber natürlich wird es nicht funktionieren. Wie kann ich es tun?


34
2018-05-08 09:41


Ursprung


Antworten:


Die Frage von OP ist schlicht JavaScript und nicht jQuery. Obwohl es viele Antworten gibt und ich @Pawan Nogariya antworte, überprüfen Sie bitte diese Alternative.

Sie können verwenden XPATH in JavaScript. Weitere Informationen zum MDN-Artikel Hier.

Das document.evaluate() Methode wertet eine XPATH-Abfrage / Ausdruck aus. So können Sie XPATH-Ausdrücke dort übergeben, in das HTML-Dokument eintauchen und das gewünschte Element finden.

In XPATH können Sie ein Element auswählen, indem Sie den Textknoten wie folgt verwenden div Das hat den folgenden Textknoten.

//div[text()="Hello World"]

Verwenden Sie Folgendes, um ein Element zu erhalten, das Text enthält:

//div[contains(., 'Hello')]

Das contains() Methode in XPATH verwendet einen Knoten als ersten Parameter und den zu suchenden Text als zweiten Parameter.

Überprüfen Sie dieses Plunk HierDies ist ein Beispiel für die Verwendung von XPATH in JavaScript

Hier ist ein Code-Snippet:

var headings = document.evaluate("//h1[contains(., 'Hello')]", document, null, XPathResult.ANY_TYPE, null );
var thisHeading = headings.iterateNext();

console.log(thisHeading); // Prints the html element in console
console.log(thisHeading.textContent); // prints the text content in console

thisHeading.innerHTML += "<br />Modified contents";  

Wie Sie sehen können, kann ich das HTML-Element greifen und es ändern, wie ich es mag.


38
2018-05-08 10:10



Da Sie es in Javascript gefragt haben, können Sie so etwas haben

function contains(selector, text) {
  var elements = document.querySelectorAll(selector);
  return Array.prototype.filter.call(elements, function(element){
    return RegExp(text).test(element.textContent);
  });
}

Und dann nenne es so

contains('div', 'sometext'); // find "div" that contain "sometext"
contains('div', /^sometext/); // find "div" that start with "sometext"
contains('div', /sometext$/i); // find "div" that end with "sometext", case-insensitive

18
2018-05-08 09:52



Sie könnten diese ziemlich einfache Lösung verwenden:

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
  1. Das Array.from wandelt die NodeList in ein Array um (dazu gibt es mehrere Methoden wie den Spread Operator oder Slice)

  2. Das Ergebnis, das jetzt ein Array ist, ermöglicht die Verwendung des Array.find Methode können Sie dann jedes Prädikat eingeben. Sie können den textContent auch mit einer Regex oder was auch immer Sie möchten überprüfen.

Beachten Sie, dass Array.from und Array.find sind ES2015-Funktionen. Sie sind kompatibel mit älteren Browsern wie IE10 ohne einen Transpiler:

Array.prototype.slice.call(document.querySelectorAll('div'))
  .filter(function (el) {
    return el.textContent === 'SomeText, text continues.'
  })[0];

11
2017-08-24 19:57



Sie sehen am besten, wenn Sie ein Elternelement des div haben, das Sie abfragen. Wenn ja, holen Sie sich das Elternelement und führen Sie ein element.querySelectorAll("div"). Sobald du das bekommst nodeList Wende einen Filter darauf an innerText Eigentum. Angenommen, ein Elternelement des div, das wir abfragen, hat ein id von container. Sie können normalerweise direkt von der ID auf den Container zugreifen, aber machen Sie es richtig.

var conty = document.getElementById("container"),
     divs = conty.querySelectorAll("div"),
    myDiv = [...divs].filter(e => e.innerText == "SomeText");

So, das war es.


3
2018-05-08 09:53



Wenn Sie jQuery oder etwas ähnliches nicht verwenden möchten, können Sie Folgendes versuchen:

function findByText(rootElement, text){
    var filter = {
        acceptNode: function(node){
            // look for nodes that are text_nodes and include the following string.
            if(node.nodeType === document.TEXT_NODE && node.nodeValue.includes(text)){
                 return NodeFilter.FILTER_ACCEPT;
            }
            return NodeFilter.FILTER_REJECT;
        }
    }
    var nodes = [];
    var walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, filter, false);
    while(walker.nextNode()){
       //give me the element containing the node
       nodes.push(walker.currentNode.parentNode);
    }
    return nodes;
}

//call it like
var nodes = findByText(document.body,'SomeText');
//then do what you will with nodes[];
for(var i = 0; i < nodes.length; i++){ 
    //do something with nodes[i]
} 

Sobald Sie die Knoten in einem Array haben, die den Text enthalten, können Sie etwas mit ihnen tun. Wie alarmieren Sie jeden oder drucken Sie zur Konsole. Ein Vorbehalt ist, dass dies nicht notwendigerweise divs per se erfassen muss, da dies das Elternelement des textnode mit dem gesuchten Text sein wird.


3
2018-05-08 10:28



Google hat dies als ein Top-Ergebnis für diejenigen, die einen Knoten mit bestimmtem Text finden müssen. Als Update ist eine Nodeliste in modernen Browsern iterierbar, ohne sie in ein Array konvertieren zu müssen.

Die Lösung kann forEach so verwenden.

var elList = document.querySelectorAll(".some .selector");
elList.forEach(function(el) {
    if (el.innerHTML.indexOf("needle") !== -1) {
        // Do what you like with el
        // The needle is case sensitive
    }
});

Das hat mir geholfen, einen Text in einer Nodelist zu suchen / zu ersetzen, wenn ein normaler Selektor nicht nur einen Knoten auswählen konnte, also musste ich jeden Knoten einzeln nach der Nadel filtern.


0
2017-11-06 22:59



Verwenden Sie XPath und document.evaluate () und stellen Sie sicher, dass Sie text () verwenden und nicht. für das Argument contains (), andernfalls wird das gesamte HTML- oder äußerste div-Element verglichen.

var headings = document.evaluate("//h1[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

oder ignorieren Sie führende und nachfolgende Leerzeichen

var headings = document.evaluate("//h1[contains(normalize-space(text()), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

oder passen Sie alle Tag-Typen an (div, h1, p, etc.)

var headings = document.evaluate("//*[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

Dann iterieren

let thisHeading;
while(thisHeading = headings.iterateNext()){
    // thisHeading contains matched node
}

0
2017-12-11 15:54



Diese Lösung führt Folgendes aus:

  • Verwendet den ES6-Spread-Operator, um die NodeList von allen zu konvertieren divs zu einem Array.

  • Stellt Ausgabe bereit, wenn der div  enthält die Abfragezeichenfolge, nicht nur wenn es genau ist ist gleich die Abfragezeichenfolge (was bei einigen anderen Antworten der Fall ist). z.B. Es sollte nicht nur für 'SomeText', sondern auch für 'SomeText, text continue' ausgegeben werden.

  • Gibt das gesamte aus div Inhalt, nicht nur die Abfragezeichenfolge. z.B. Für 'SomeText, Text wird fortgesetzt' sollte es die ganze Zeichenfolge ausgeben, nicht nur 'SomeText'.

  • Erlaubt mehrere divs, um die Zeichenfolge zu enthalten, nicht nur eine einzelne div.

[...document.querySelectorAll('div')]      // get all the divs in an array
  .map(div => div.innerHTML)               // get their contents
  .filter(txt => txt.includes('SomeText')) // keep only those containing the query
  .forEach(txt => console.log(txt));       // output the entire contents of those
<div>SomeText, text continues.</div>
<div>Not in this div.</div>
<div>Here is more SomeText.</div>


0
2018-04-12 03:32