Як отримати елемент через innerText


Відповіді:


148

Вам доведеться переходити вручну.

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 Насправді внутрішнійHTML є стандартним. innerText не працює у FF
AnaMaria

Оновлений приклад, textContent - це, ймовірно, те, що ви хочете в цьому випадку. Дякую, люди :)
Серпень Ліллеас

1
@AugustLilleaas, що з цим i < il? Що це робиш?
Девід Сойєр

1
Я виявив, що якщо у вас є <span> <span> текст пошуку </span> </span>, цей метод може повернути зовнішній проміжок замість внутрішнього.
Кевін Вілер

5
Ні, це питання стосується JavaScript та HTML, а не Java
серпень Lilleaas

160

Ви можете використовувати xpath для цього

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

Ви також можете шукати елемент, що містить деякий текст, використовуючи цей xpath:

var xpath = "//a[contains(text(),'Searching')]";

7
Це має бути головна відповідь. XPath може зробити набагато більше, як вибрати вузол за значенням атрибута, вибрати набори вузлів ... Просте вступ: w3schools.com/xml/xpath_syntax.asp
Timathon

1
Питання полягає в тому, яка покарання за цю хитрість
vsync

2
@vsync Я думаю, що це буде швидше, ніж будь-який з інших відповідей, оскільки xpath виконується алгоритмом, який надається браузером, а не виконує javascript, як і всі інші відповіді тут. Хоча це цікаве питання.
carlin.scott

1
Здається Document.evaluate() , в браузері IE не передбачається
vsync

1
Я не знаю чому, але якось var xpath = "//a[text()='SearchingText']"; це не працює, але var xpath = "//a[contains(text(),'Searching')]"; це працює. Будьте в курсі розкопаного символу, такого як \ '\'.
Joey Cho

38

Використовуючи найсучасніший на даний момент синтаксис, це можна зробити дуже чисто так:

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

Або з окремим фільтром:

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

Звичайно, застарілі браузери не впораються з цим, але ви можете використовувати транспілер, якщо потрібна підтримка застарілих.


<3 фільтр
Джон Вандів'є

36

Ви можете використовувати jQuery : contains () Selector

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

Я отримую: Error: <![EX[["Tried to get element with id of \"%s\" but it is not present on the page","a:contains('SearchingText')"]]]> TAAL[1]хоча в мене є елементи з "SearchingText".
Рішабх Аграхарі

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>

Звичайно, все-таки дещо простішим способом є:

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>

Список літератури:


14

Функціональний підхід. Повертає масив усіх відповідних елементів та обробляє пробіли навколо під час перевірки.

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

Використання

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

якщо ви переглядаєте різні теги, тобто проміжок або кнопку

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

Значення за замовчуванням тег = 'a' знадобиться Babel для старих браузерів


Це неправильно, оскільки він також містить результати для всіх дочірніх вузлів. Тобто, якщо дочірній вузол aбуде містити str- elбуде включений в getElementsByTextрезультат; що неправильно.
avalanche1

@ lalanche1 - це залежить, якщо це небажано. Це може знадобитися для вибору за текстом, навіть якщо він загорнутий у інший тег, тобто <span> </span>
Pawel

5

Просто переведіть підрядку в наступний рядок:

Зовнішній HTML

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

Внутрішній HTML

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

Ви можете використовувати їх для пошуку у всьому документі та пошуку тегів, які містять пошуковий термін:

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

Використання :

Скільки разів на цій сторінці згадується користувач "T3rm1"?

get_elements_by_inner("T3rm1").length

1

Скільки разів згадується jQuery?

get_elements_by_inner("jQuery").length

3

Отримайте всі елементи, що містять слово "Кібернетичний":

get_elements_by_inner("Cybernetic")

введіть тут опис зображення


Це повертає true чи false, але не елемент.
T3rm1

Ви можете використовувати умову істини, щоб перебрати через отримані елементи і захопити все необхідне з цих елементів. Дивіться оновлену відповідь.
Кібернетичний

4

Я знайшов використання новішого синтаксису трохи коротшим порівняно з відповіддю інших. Ось ось моя пропозиція:

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

Щоб отримати метод фільтра від user1106925, який працює в <= IE11, якщо потрібно

Ви можете замінити оператора спред на:

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

і включає дзвінок з a.textContent.match("your search term")

яка працює досить акуратно:

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

Мені подобається цей метод. Можна також Array.fromзамість [].slice.call. Наприклад: Array.from(document.querySelectorAll('a'))
Річард

1

Хоча можна дістатись до внутрішнього тексту, я думаю, ви рухаєтесь неправильним шляхом. Динамічно генерується ця внутрішня струна? Якщо так, ви можете дати тегу клас або - ще краще - ідентифікатор, коли текст надходить туди. Якщо це статично, то це ще простіше.


1

Ви можете використовувати a TreeWalkerдля переходу по вузлах DOM та пошуку всіх текстових вузлів, які містять текст, та повернення їх батьків:

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

Це робить роботу.
Повертає масив вузлів, що містять 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

Я думаю, що вам потрібно буде трохи конкретніше, щоб ми допомогли вам.

  1. Як ви це знаходите? Javascript? PHP? Perl?
  2. Чи можете ви застосувати атрибут ID до тегу?

Якщо текст унікальний (або насправді, якщо його немає, але вам доведеться пробігти через масив), ви можете запустити регулярний вираз, щоб знайти його. Використання PHP's preg_match () буде працювати для цього.

Якщо ви використовуєте Javascript і можете вставити атрибут ідентифікатора, ви можете використовувати getElementById ('id'). Потім ви можете отримати доступ до атрибутів повернутого елемента через DOM: https://developer.mozilla.org/en/DOM/element.1 .


0

Мені просто потрібен спосіб отримати елемент, який містить конкретний текст, і ось що я придумав.

Використовуйте document.getElementsByInnerText()для отримання декількох елементів (декілька елементів можуть мати однаковий точний текст) та використовуйте document.getElementByInnerText()для отримання лише одного елемента (перша відповідність).

Також ви можете локалізувати пошук, використовуючи someElement.getElementByInnerText()замість елемента (наприклад ) document.

Вам може знадобитися налаштувати його, щоб зробити його перехресним браузером або задовольнити ваші потреби.

Я думаю, що код пояснює себе, тому я залишу його таким, яким він є.

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.