Jak uzyskać element przez innerText

Odpowiedzi:

148

Będziesz musiał przejść ręcznie.

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
źródło
1
@AutoSponge Właściwie innerHTML jest standardem. innerText nie działa w FF
AnaMaria
Zaktualizowany przykład, textContent jest prawdopodobnie tym, czego chcesz w tym przypadku. Dzięki, ludzie :)
August Lilleaas
1
@AugustLilleaas, o co chodzi z tym i < il? Co to robi?
David Sawyer,
1
Odkryłem, że jeśli masz <span> <span> tekst wyszukiwania </span> </span>, ta metoda może zwrócić zewnętrzny zakres zamiast wewnętrznego.
Kevin Wheeler
5
Nie, to pytanie dotyczy JavaScript i HTML, a nie Java
sierpień Lilleaas
160

Aby to osiągnąć, możesz użyć xpath

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

Możesz również wyszukać element zawierający tekst, używając tej ścieżki xpath:

var xpath = "//a[contains(text(),'Searching')]";
carlin.scott
źródło
7
To powinna być najlepsza odpowiedź. XPath może zrobić znacznie więcej, na przykład wybierać węzeł według wartości atrybutu, wybierać zestawy węzłów ... Proste wprowadzenie: w3schools.com/xml/xpath_syntax.asp
Timathon
1
Pytanie brzmi, jaka jest kara wydajności dla tej sztuczki
vsync
2
@vsync Myślę, że będzie to szybsze niż jakakolwiek inna odpowiedź, ponieważ xpath jest wykonywany przez algorytm dostarczony przez przeglądarkę, a nie w javascript, jak wszystkie inne odpowiedzi tutaj. Jest to jednak interesujące pytanie.
carlin.scott
1
Wydaje Document.evaluate() się, że nie jest to oczekiwane w przeglądarce IE
vsync
1
Nie wiem dlaczego, ale jakoś var xpath = "//a[text()='SearchingText']"; to nie działa, ale var xpath = "//a[contains(text(),'Searching')]"; to działa. Zwróć uwagę na wykluczony znak, taki jak \ '\'.
Joey Cho
38

Korzystając z najnowocześniejszej obecnie dostępnej składni, można to zrobić bardzo czysto w następujący sposób:

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

Lub z osobnym filtrem:

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

Oczywiście starsze przeglądarki tego nie obsługują, ale możesz użyć transpilera, jeśli potrzebna jest starsza obsługa.

user1106925
źródło
<Podejście z 3 filtrami
John Vandivier
36

Możesz użyć selektora jQuery : zawiera ()

var element = $( "a:contains('SearchingText')" );
Mouneer
źródło
Dostaję: Error: <![EX[["Tried to get element with id of \"%s\" but it is not present on the page","a:contains('SearchingText')"]]]> TAAL[1]chociaż mam w sobie elementy z "SearchingText".
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>

Oczywiście nieco prostszym sposobem jest nadal:

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>

Bibliografia:

David mówi, że przywróć Monikę
źródło
14

Podejście funkcjonalne. Zwraca tablicę wszystkich dopasowanych elementów i przycina spacje dookoła podczas sprawdzania.

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

Stosowanie

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

jeśli przeglądasz różne tagi, np. zakres lub przycisk

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

Domyślny tag wartości = „a” będzie wymagał Babel w starszych przeglądarkach

Paweł
źródło
Jest to niepoprawne, ponieważ zawiera również wyniki dla wszystkich węzłów podrzędnych. To znaczy, jeśli węzeł potomny abędzie zawierał str- elzostanie uwzględniony w getElementsByTextwyniku; co jest złe.
lawina 1
@ avalanche1 to zależy, czy jest to niepożądane. Może być konieczne wybranie tekstu, nawet jeśli jest on zawinięty w inny tag, np. <span> </span>
Paweł
5

Po prostu przekaż podciąg do następującego wiersza:

Zewnętrzny HTML

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

Wewnętrzny HTML

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

Możesz ich używać do przeszukiwania całego dokumentu i pobierania tagów zawierających wyszukiwane hasło:

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

Zastosowanie :

Ile razy jest mowa o użytkowniku „T3rm1” na tej stronie?

get_elements_by_inner("T3rm1").length

1

Ile razy wspomniano o jQuery?

get_elements_by_inner("jQuery").length

3

Pobierz wszystkie elementy zawierające słowo „Cybernetic”:

get_elements_by_inner("Cybernetic")

wprowadź opis obrazu tutaj

Cybernetyczny
źródło
Zwraca prawdę lub fałsz, ale nie zwraca elementu.
T3rm1
Możesz użyć warunku prawdy, aby iterować po pobranych elementach i pobrać z nich wszystko, czego potrzebujesz. Zobacz zaktualizowaną odpowiedź.
Cybernetic
4

Uważam, że użycie nowszej składni jest nieco krótsze w porównaniu z innymi odpowiedziami. Oto moja propozycja:

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
źródło
2

Aby uzyskać metodę filtru od user1106925 pracującego w <= IE11, jeśli to konieczne

Operator spreadu można zamienić na:

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

a obejmuje połączenie z a.textContent.match("your search term")

który działa całkiem nieźle:

[].slice.call(document.querySelectorAll("a"))
   .filter(a => a.textContent.match("your search term"))
   .forEach(a => console.log(a.textContent))
Alkie
źródło
Podoba mi się ta metoda. Możesz też Array.fromzamiast [].slice.call. Na przykład: Array.from(document.querySelectorAll('a'))
Richard
1

Chociaż możliwe jest zapoznanie się z tekstem wewnętrznym, myślę, że zmierzasz w złym kierunku. Czy ten wewnętrzny ciąg jest generowany dynamicznie? Jeśli tak, możesz nadać tagowi klasę lub - jeszcze lepiej - identyfikator, gdy tekst zostanie tam umieszczony. Jeśli jest statyczny, jest jeszcze łatwiej.

Zack Marrapese
źródło
1

Możesz użyć a, TreeWalkeraby przejść przez węzły DOM i zlokalizować wszystkie węzły tekstowe, które zawierają tekst, i zwrócić ich rodziców:

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
źródło
1

To spełnia swoje zadanie.
Zwraca tablicę węzłów zawierającą 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())
    );
  }
lawina 1
źródło
0

Myślę, że abyśmy mogli Ci pomóc, musisz być bardziej szczegółowy.

  1. Jak to znalazłeś? Javascript? PHP? Perl?
  2. Czy możesz zastosować atrybut ID do tagu?

Jeśli tekst jest unikalny (lub naprawdę, jeśli nie jest, ale musiałbyś przejść przez tablicę), możesz uruchomić wyrażenie regularne, aby go znaleźć. Do tego zadziała użycie preg_match () PHP.

Jeśli korzystasz z JavaScript i możesz wstawić atrybut ID, możesz użyć metody getElementById („id”). Następnie możesz uzyskać dostęp do atrybutów zwróconego elementu poprzez DOM: https://developer.mozilla.org/en/DOM/element.1 .

Jeff Meyers
źródło
0

Po prostu potrzebowałem sposobu, aby uzyskać element, który zawiera określony tekst i oto, co wymyśliłem.

Użyj, document.getElementsByInnerText()aby uzyskać wiele elementów (wiele elementów może mieć dokładnie ten sam tekst) i użyj, document.getElementByInnerText()aby uzyskać tylko jeden element (pierwsze dopasowanie).

Możesz również zlokalizować wyszukiwanie, używając elementu (np. someElement.getElementByInnerText()) Zamiast document.

Może być konieczne dostosowanie go, aby działał w różnych przeglądarkach lub spełniał Twoje potrzeby.

Myślę, że kod jest oczywisty, więc zostawię go tak, jak jest.

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
źródło