Cara mendapatkan elemen dengan innerText

Jawaban:

147

Anda harus melintasi dengan tangan.

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`.
Lilleaas Agustus
sumber
1
@ AutoSponge Sebenarnya innerHTML adalah standar. innerText tidak berfungsi di FF
AnaMaria
Diperbarui contoh, textContent kemungkinan apa yang Anda inginkan dalam kasus ini. Terima kasih, teman-teman :)
August Lilleaas
1
@ AgugLilleaas, ada apa dengan ini i < il? Apa yang sedang dilakukan?
David Sawyer
1
Saya telah menemukan bahwa jika Anda memiliki <span> <span> teks pencarian </span> </span> metode ini dapat mengembalikan rentang terluar daripada yang dalam.
Kevin Wheeler
5
Tidak, pertanyaan ini tentang JavaScript dan HTML, bukan Java
Agustus Lilleaas
160

Anda bisa menggunakan xpath untuk mencapai ini

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

Anda juga dapat mencari elemen yang mengandung beberapa teks menggunakan xpath ini:

var xpath = "//a[contains(text(),'Searching')]";
carlin.scott
sumber
7
Ini harus menjadi jawaban teratas. XPath dapat melakukan lebih banyak lagi, seperti pilih simpul berdasarkan nilai atribut, pilih set simpul ... Intro sederhana: w3schools.com/xml/xpath_syntax.asp
Timathon
1
Pertanyaannya adalah, apa hukuman performa untuk tipuan ini
vsync
2
@vsync Saya pikir ini akan lebih cepat daripada jawaban lain karena xpath dieksekusi oleh algoritma yang disediakan browser daripada mengeksekusi dalam javascript seperti semua jawaban lain di sini. Ini pertanyaan yang menarik.
carlin.scott
1
Tampaknya Document.evaluate() tidak seharusnya di browser IE
vsync
1
Saya tidak tahu mengapa, tapi entah bagaimana var xpath = "//a[text()='SearchingText']"; ini tidak berhasil, tetapi var xpath = "//a[contains(text(),'Searching')]"; ini berhasil. Waspadai karakter yang diekskapasi, seperti \ '\'.
Joey Cho
38

Menggunakan sintaksis paling modern yang tersedia saat ini, dapat dilakukan dengan sangat bersih seperti ini:

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

Atau dengan filter terpisah:

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

Secara alami, browser lawas tidak akan menangani ini, tetapi Anda dapat menggunakan transpiler jika diperlukan dukungan legacy.

pengguna1106925
sumber
<3 pendekatan filter
John Vandivier
36

Anda dapat menggunakan jQuery : berisi () Pemilih

var element = $( "a:contains('SearchingText')" );
Mouneer
sumber
Saya mendapatkan: Error: <![EX[["Tried to get element with id of \"%s\" but it is not present on the page","a:contains('SearchingText')"]]]> TAAL[1]meskipun saya memiliki elemen dengan "SearchingText" di dalamnya.
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>

Tentu saja, cara yang agak lebih sederhana adalah:

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>

Referensi:

David mengatakan mengembalikan Monica
sumber
14

Pendekatan fungsional. Mengembalikan array semua elemen yang cocok dan memangkas ruang di sekitar saat memeriksa.

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

Pemakaian

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

jika Anda mencari melalui tag yang berbeda yaitu bentang atau tombol

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

Tag nilai default = 'a' akan membutuhkan Babel untuk browser lama

Pawel
sumber
Ini tidak benar karena juga termasuk hasil untuk semua node anak. Yaitu jika simpul anak aakan mengandung str- elakan dimasukkan ke dalam getElementsByTexthasil; mana yang salah
avalanche1
@ avalanche1 itu tergantung jika itu tidak diinginkan. Mungkin diperlukan untuk memilih dengan teks bahkan jika itu dibungkus dengan tag lain yaitu <span> </span>
Pawel
5

Cukup masukkan substring Anda ke baris berikut:

HTML luar

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

HTML bagian dalam

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

Anda dapat menggunakan ini untuk mencari di seluruh dokumen dan mengambil tag yang berisi istilah pencarian Anda:

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

Penggunaan :

Berapa kali pengguna "T3rm1" disebutkan di halaman ini?

get_elements_by_inner("T3rm1").length

1

Berapa kali jQuery disebutkan?

get_elements_by_inner("jQuery").length

3

Dapatkan semua elemen yang mengandung kata "Cybernetic":

get_elements_by_inner("Cybernetic")

masukkan deskripsi gambar di sini

Berhubung dgn sibernetika
sumber
Ini mengembalikan benar atau salah tetapi bukan elemen.
T3rm1
Anda dapat menggunakan kondisi kebenaran untuk beralih melalui elemen yang diambil dan mengambil apa pun yang Anda butuhkan dari elemen tersebut. Lihat jawaban yang diperbarui.
Cybernetic
4

Saya menemukan penggunaan sintaks yang lebih baru sedikit lebih pendek dibandingkan dengan jawaban yang lain. Jadi, inilah proposal saya:

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
sumber
2

Untuk mendapatkan metode filter dari user1106925 bekerja di <= IE11 jika diperlukan

Anda dapat mengganti operator spread dengan:

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

dan termasuk panggilan dengan a.textContent.match("your search term")

yang bekerja dengan cukup rapi:

[].slice.call(document.querySelectorAll("a"))
   .filter(a => a.textContent.match("your search term"))
   .forEach(a => console.log(a.textContent))
Alkie
sumber
Saya suka metode ini. Anda juga dapat Array.frombukan [].slice.call. Misalnya: Array.from(document.querySelectorAll('a'))
Richard
1

Meskipun mungkin untuk memahami teks dalam, saya pikir Anda salah arah. Apakah string dalam itu dihasilkan secara dinamis? Jika demikian, Anda dapat memberikan tag pada kelas atau - lebih baik lagi - ID saat teks masuk ke sana. Jika statis, maka itu bahkan lebih mudah.

Zack Marrapese
sumber
1

Anda dapat menggunakan a TreeWalkeruntuk memeriksa node DOM, dan mencari semua node teks yang berisi teks, dan mengembalikan orang tua mereka:

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
sumber
1

Ini berhasil.
Mengembalikan array node yang berisi 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())
    );
  }
longsoran1
sumber
0

Saya pikir Anda harus sedikit lebih spesifik agar kami dapat membantu Anda.

  1. Bagaimana Anda menemukan ini? Javascript? PHP? Perl?
  2. Bisakah Anda menerapkan atribut ID ke tag?

Jika teksnya unik (atau benar-benar, jika tidak, tetapi Anda harus menjalankan array) Anda bisa menjalankan ekspresi reguler untuk menemukannya. Menggunakan PHP preg_match () akan bekerja untuk itu.

Jika Anda menggunakan Javascript dan dapat menyisipkan atribut ID, maka Anda dapat menggunakan getElementById ('id'). Anda kemudian dapat mengakses atribut elemen yang dikembalikan melalui DOM: https://developer.mozilla.org/en/DOM/element.1 .

Jeff Meyers
sumber
0

Saya hanya perlu cara untuk mendapatkan elemen yang berisi teks tertentu dan inilah yang saya buat.

Gunakan document.getElementsByInnerText()untuk mendapatkan banyak elemen (beberapa elemen mungkin memiliki teks persis sama), dan gunakan document.getElementByInnerText()untuk mendapatkan hanya satu elemen (kecocokan pertama).

Selain itu, Anda dapat melokalkan pencarian dengan menggunakan elemen (mis. someElement.getElementByInnerText()) Alih-alih document.

Anda mungkin perlu mengubah itu untuk membuatnya lintas-browser atau memenuhi kebutuhan Anda.

Saya pikir kode ini cukup jelas, jadi saya akan membiarkannya apa adanya.

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
sumber