So erhalten Sie ein Element von innerText

Antworten:

146

Sie müssen von Hand durchqueren.

var aTags = document.getElementsByTagName("a");
var searchText = "SearchingText";
var found;

for (var i = 0; i < aTags.length; i++) {
  if (aTags[i].textContent == searchText) {
    found = aTags[i];
    break;
  }
}

// Use `found`.
August Lilleaas
quelle
1
@AutoSponge Eigentlich ist innerHTML Standard. innerText funktioniert nicht in FF
AnaMaria
Das Beispiel wurde aktualisiert. TextContent ist wahrscheinlich das, was Sie in diesem Fall möchten. Danke, Leute :)
August Lilleaas
1
@ AugustLilleaas, was ist mit dem i < illos? Was macht das
David Sawyer
1
Ich habe festgestellt, dass bei <span> <span> Suchtext </ span> </ span> diese Methode möglicherweise die äußere anstelle der inneren Spanne zurückgibt.
Kevin Wheeler
5
Nein, diese Frage
bezieht sich auf
159

Sie können xpath verwenden, um dies zu erreichen

var xpath = "//a[text()='SearchingText']";
var matchingElement = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

Mit diesem xpath können Sie auch nach einem Element suchen, das Text enthält:

var xpath = "//a[contains(text(),'Searching')]";
carlin.scott
quelle
7
Dies sollte die beste Antwort sein. XPath kann viel mehr, wie Knoten nach Attributwert auswählen, Knotensätze
Timathon
1
Die Frage ist, was ist die Leistungsstrafe für diesen Trick
vsync
2
@vsync Ich denke, dies ist schneller als jede andere Antwort, da der xpath von einem vom Browser bereitgestellten Algorithmus ausgeführt wird, anstatt wie alle anderen Antworten hier in Javascript ausgeführt zu werden. Es ist jedoch eine interessante Frage.
carlin.scott
1
Scheint Document.evaluate() nicht im IE- Browser
vsync
1
Ich weiß nicht warum, aber irgendwie var xpath = "//a[text()='SearchingText']"; funktioniert das nicht, aber var xpath = "//a[contains(text(),'Searching')]"; das funktioniert. Achten Sie auf den ausgegrabenen Charakter, z. B. \ '\'.
Joey Cho
38

Mit der derzeit modernsten Syntax kann dies sehr sauber gemacht werden:

for (const a of document.querySelectorAll("a")) {
  if (a.textContent.includes("your search term")) {
    console.log(a.textContent)
  }
}

Oder mit einem separaten Filter:

[...document.querySelectorAll("a")]
   .filter(a => a.textContent.includes("your search term"))
   .forEach(a => console.log(a.textContent))

Natürlich werden ältere Browser dies nicht verarbeiten, aber Sie können einen Transpiler verwenden, wenn ältere Unterstützung benötigt wird.

user1106925
quelle
<3 Filter Ansatz
John Vandivier
36

Sie können jQuery : enthält () Selector verwenden

var element = $( "a:contains('SearchingText')" );
Mouneer
quelle
Ich bekomme: Error: <![EX[["Tried to get element with id of \"%s\" but it is not present on the page","a:contains('SearchingText')"]]]> TAAL[1]obwohl ich Elemente mit "SearchingText" habe.
Rishabh Agrahari
15

function findByTextContent(needle, haystack, precise) {
  // needle: String, the string to be found within the elements.
  // haystack: String, a selector to be passed to document.querySelectorAll(),
  //           NodeList, Array - to be iterated over within the function:
  // precise: Boolean, true - searches for that precise string, surrounded by
  //                          word-breaks,
  //                   false - searches for the string occurring anywhere
  var elems;

  // no haystack we quit here, to avoid having to search
  // the entire document:
  if (!haystack) {
    return false;
  }
  // if haystack is a string, we pass it to document.querySelectorAll(),
  // and turn the results into an Array:
  else if ('string' == typeof haystack) {
    elems = [].slice.call(document.querySelectorAll(haystack), 0);
  }
  // if haystack has a length property, we convert it to an Array
  // (if it's already an array, this is pointless, but not harmful):
  else if (haystack.length) {
    elems = [].slice.call(haystack, 0);
  }

  // work out whether we're looking at innerText (IE), or textContent 
  // (in most other browsers)
  var textProp = 'textContent' in document ? 'textContent' : 'innerText',
    // creating a regex depending on whether we want a precise match, or not:
    reg = precise === true ? new RegExp('\\b' + needle + '\\b') : new RegExp(needle),
    // iterating over the elems array:
    found = elems.filter(function(el) {
      // returning the elements in which the text is, or includes,
      // the needle to be found:
      return reg.test(el[textProp]);
    });
  return found.length ? found : false;;
}


findByTextContent('link', document.querySelectorAll('li'), false).forEach(function(elem) {
  elem.style.fontSize = '2em';
});

findByTextContent('link3', 'a').forEach(function(elem) {
  elem.style.color = '#f90';
});
<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

Ein etwas einfacherer Weg ist natürlich noch:

var textProp = 'textContent' in document ? 'textContent' : 'innerText';

// directly converting the found 'a' elements into an Array,
// then iterating over that array with Array.prototype.forEach():
[].slice.call(document.querySelectorAll('a'), 0).forEach(function(aEl) {
  // if the text of the aEl Node contains the text 'link1':
  if (aEl[textProp].indexOf('link1') > -1) {
    // we update its style:
    aEl.style.fontSize = '2em';
    aEl.style.color = '#f90';
  }
});
<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

Verweise:

David sagt, Monica wieder einsetzen
quelle
14

Funktionaler Ansatz. Gibt ein Array aller übereinstimmenden Elemente zurück und schneidet beim Überprüfen Leerzeichen ab.

function getElementsByText(str, tag = 'a') {
  return Array.prototype.slice.call(document.getElementsByTagName(tag)).filter(el => el.textContent.trim() === str.trim());
}

Verwendung

getElementsByText('Text here'); // second parameter is optional tag (default "a")

Wenn Sie durch verschiedene Tags schauen, z. B. span oder button

getElementsByText('Text here', 'span');
getElementsByText('Text here', 'button');

Der Standardwert tag = 'a' benötigt Babel für alte Browser

Pawel
quelle
Dies ist falsch, da es auch Ergebnisse für alle untergeordneten Knoten enthält. Dh wenn der untergeordnete Knoten von awill enthält str- elwird in das getElementsByTextErgebnis aufgenommen; was falsch ist.
avalanche1
@ avalanche1 es kommt darauf an, ob das unerwünscht ist. Es kann erforderlich sein, per Text auszuwählen, auch wenn es in ein anderes Tag eingewickelt ist, dh <span> </ span>
Pawel
5

Geben Sie einfach Ihren Teilstring in die folgende Zeile ein:

Äußeres HTML

document.documentElement.outerHTML.includes('substring')

Inneres HTML

document.documentElement.innerHTML.includes('substring')

Mit diesen können Sie das gesamte Dokument durchsuchen und die Tags abrufen, die Ihren Suchbegriff enthalten:

function get_elements_by_inner(word) {
    res = []
    elems = [...document.getElementsByTagName('a')];
    elems.forEach((elem) => { 
        if(elem.outerHTML.includes(word)) {
            res.push(elem)
        }
    })
    return(res)
}

Verwendung :

Wie oft wird der Benutzer "T3rm1" auf dieser Seite erwähnt?

get_elements_by_inner("T3rm1").length

1

Wie oft wird jQuery erwähnt?

get_elements_by_inner("jQuery").length

3

Holen Sie sich alle Elemente mit dem Wort "Kybernetisch":

get_elements_by_inner("Cybernetic")

Geben Sie hier die Bildbeschreibung ein

Kybernetisch
quelle
Dies gibt true oder false zurück, jedoch nicht das Element.
T3rm1
Sie können die Wahrheitsbedingung verwenden, um die abgerufenen Elemente zu durchlaufen und alles zu holen, was Sie von diesen Elementen benötigen. Siehe aktualisierte Antwort.
Kybernetik
4

Ich fand die Verwendung der neueren Syntax im Vergleich zu den anderen Antworten etwas kürzer. Also hier ist mein Vorschlag:

const callback = element => element.innerHTML == 'My research'

const elements = Array.from(document.getElementsByTagName('a'))
// [a, a, a, ...]

const result = elements.filter(callback)

console.log(result)
// [a]

JSfiddle.net

Amin NAIRI
quelle
2

So rufen Sie die Filtermethode von user1106925 ab Arbeits in <= IE11 , wenn nötig

Sie können den Spread-Operator ersetzen durch:

[].slice.call(document.querySelectorAll("a"))

und das schließt Anruf mit ein a.textContent.match("your search term")

das funktioniert ganz ordentlich:

[].slice.call(document.querySelectorAll("a"))
   .filter(a => a.textContent.match("your search term"))
   .forEach(a => console.log(a.textContent))
Alkie
quelle
Ich mag diese Methode. Sie können auch Array.fromanstelle von [].slice.call. Zum Beispiel: Array.from(document.querySelectorAll('a'))
Richard
1

Es ist zwar möglich, an den inneren Text heranzukommen, aber ich denke, Sie gehen in die falsche Richtung. Wird diese innere Zeichenfolge dynamisch generiert? In diesem Fall können Sie dem Tag eine Klasse oder - noch besser - eine ID geben, wenn der Text dort eingeht. Wenn es statisch ist, ist es noch einfacher.

Zack Marrapese
quelle
1

Mit a können Sie TreeWalkerdie DOM-Knoten durchsuchen, alle Textknoten suchen, die den Text enthalten, und ihre Eltern zurückgeben:

const findNodeByContent = (text, root = document.body) => {
  const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);

  const nodeList = [];

  while (treeWalker.nextNode()) {
    const node = treeWalker.currentNode;

    if (node.nodeType === Node.TEXT_NODE && node.textContent.includes(text)) {
      nodeList.push(node.parentNode);
    }
  };

  return nodeList;
}

const result = findNodeByContent('SearchingText');

console.log(result);
<a ...>SearchingText</a>

Ori Drori
quelle
0

Ich denke, Sie müssen etwas spezifischer sein, damit wir Ihnen helfen können.

  1. Wie findest du das? Javascript? PHP? Perl?
  2. Können Sie dem Tag ein ID-Attribut zuweisen?

Wenn der Text eindeutig ist (oder wirklich nicht, aber Sie müssten ein Array durchlaufen), können Sie einen regulären Ausdruck ausführen, um ihn zu finden. Die Verwendung von preg_match () von PHP würde dafür funktionieren.

Wenn Sie Javascript verwenden und ein ID-Attribut einfügen können, können Sie getElementById ('id') verwenden. Sie können dann über das DOM auf die Attribute des zurückgegebenen Elements zugreifen: https://developer.mozilla.org/en/DOM/element.1 .

Jeff Meyers
quelle
0

Ich brauchte nur einen Weg, um das Element zu erhalten, das einen bestimmten Text enthält, und das habe ich mir ausgedacht.

Verwenden Sie document.getElementsByInnerText()diese Option , um mehrere Elemente abzurufen (mehrere Elemente haben möglicherweise denselben exakten Text), und verwenden Sie document.getElementByInnerText()diese Option, um nur ein Element abzurufen (erste Übereinstimmung).

Sie können die Suche auch lokalisieren, indem Sie ein Element (z. B. someElement.getElementByInnerText()) anstelle von verwendendocument . .

Möglicherweise müssen Sie es optimieren, um es browserübergreifend zu gestalten oder Ihre Anforderungen zu erfüllen.

Ich denke, der Code ist selbsterklärend, also lasse ich ihn so wie er ist.

HTMLElement.prototype.getElementsByInnerText = function (text, escape) {
    var nodes  = this.querySelectorAll("*");
    var matches = [];
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].innerText == text) {
            matches.push(nodes[i]);
        }
    }
    if (escape) {
        return matches;
    }
    var result = [];
    for (var i = 0; i < matches.length; i++) {
        var filter = matches[i].getElementsByInnerText(text, true);
        if (filter.length == 0) {
            result.push(matches[i]);
        }
    }
    return result;
};
document.getElementsByInnerText = HTMLElement.prototype.getElementsByInnerText;

HTMLElement.prototype.getElementByInnerText = function (text) {
    var result = this.getElementsByInnerText(text);
    if (result.length == 0) return null;
    return result[0];
}
document.getElementByInnerText = HTMLElement.prototype.getElementByInnerText;

console.log(document.getElementsByInnerText("Text1"));
console.log(document.getElementsByInnerText("Text2"));
console.log(document.getElementsByInnerText("Text4"));
console.log(document.getElementsByInnerText("Text6"));

console.log(document.getElementByInnerText("Text1"));
console.log(document.getElementByInnerText("Text2"));
console.log(document.getElementByInnerText("Text4"));
console.log(document.getElementByInnerText("Text6"));
<table>
    <tr>
        <td>Text1</td>
    </tr>
    <tr>
        <td>Text2</td>
    </tr>
    <tr>
        <td>
            <a href="#">Text2</a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#"><span>Text3</span></a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#">Special <span>Text4</span></a>
        </td>
    </tr>
    <tr>
        <td>
            Text5
            <a href="#">Text6</a>
            Text7
        </td>
    </tr>
</table>

Akinuri
quelle
0

Das macht den Job.
Gibt ein Array von Knoten zurück, die enthalten text.

function get_nodes_containing_text(selector, text) {
    const elements = [...document.querySelectorAll(selector)];

    return elements.filter(
      (element) =>
        element.childNodes[0]
        && element.childNodes[0].nodeValue
        && RegExp(text, "u").test(element.childNodes[0].nodeValue.trim())
    );
  }
Lawine1
quelle