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`.

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')]";

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.


<Podejście z 3 filtrami
John Vandivier

36

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

var element = $( "a:contains('SearchingText')" );

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:


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


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


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


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

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.


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>


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())
    );
  }

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 .


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>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.