2010-09-28 12 views
55

Come ottenere il tag nella pagina html, se so cosa contiene il tag di testo. Es .:Come ottenere l'elemento di innerText

<a ...>SearchingText</a> 
+0

pulite, approccio funzionale corrispondente alla matrice https: // StackOverflow.com/a/45089849/696535 – Pawel

risposta

65

dovrete attraversare a mano.

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 In realtà innerHTML è standard. innerText non funziona in FF – AnaMaria

+0

Aggiornato l'esempio, textContent è probabilmente quello che vuoi in questo caso. Grazie, gente :) –

+1

@AugustLilleaas, che succede con il 'i

0

Mentre è possibile ottenere il testo interno, penso che ci si sta muovendo nella direzione sbagliata. Quella stringa interna è generata dinamicamente? Se è così, puoi dare al tag una classe o, meglio ancora, un ID quando il testo va lì. Se è statico, è ancora più semplice.

0

Penso che dovrai essere un po 'più specifico per noi per aiutarti.

  1. Come state trovando questo? Javascript? PHP? Perl?
  2. È possibile applicare un attributo ID al tag?

Se il testo è univoco (o in realtà, se non lo è, ma è necessario eseguire un array) è possibile eseguire un'espressione regolare per trovarlo. Usare il preg_match() di PHP funzionerebbe per quello.

Se si utilizza Javascript e si può inserire un attributo ID, è possibile utilizzare getElementById ('id'). È quindi possibile accedere agli attributi dell'elemento restituito tramite il DOM: https://developer.mozilla.org/en/DOM/element.1.

14

Mentre è passato un bel po 'di tempo, e hai già (a lungo da allora) ha accettato una risposta, ho pensato di offrire un approccio aggiornato:

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>

Naturalmente , un modo un po 'più semplice è ancora:

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>

Riferimenti:

33

Si potrebbe usare XPath per raggiungere questo

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

è possibile cercare anche di un elemento che contiene un testo utilizzando questo XPath:

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

Questa dovrebbe essere la risposta migliore. XPath può fare molto di più, come selezionare nodo per valore di attributo, selezionare set di nodi ... Semplice introduzione: https://www.w3schools.com/xml/xpath_syntax.asp – Timathon

+0

Semplice, elegante e avanzato. Migliore risposta. –

+0

La domanda è, qual è la penalità delle prestazioni per questo inganno – vsync

9

Utilizzando la sintassi più moderna a vailable al momento, può essere fatto in modo molto pulito come questo:

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

o con un filtro separato:

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

Naturalmente, i browser legacy non gestirà questo, ma è possibile utilizzare un transpiler se è necessario il supporto legacy.

1

Ho trovato l'uso della sintassi più recente un po 'più breve rispetto alla risposta di altri. Quindi, ecco la mia proposta:

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

4

approccio funzionale. Restituisce la matrice di tutti gli elementi abbinati e assegna gli spazi intorno durante il controllo.

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

Uso

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

se siete alla ricerca attraverso diversi tag vale a dire frammento o un tasto

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

Il valore di default tag = 'a' avrà bisogno di Babel per vecchi browser

-2

jQuery version:

 

$('.class_name').each(function(i) { 
    var $element = $(this)[i]; 

    if($element.text() == 'Your Text') { 
     /** Do Something */ 
    } 
}); 

-1

Ho appena avuto bisogno di un modo per ottenere l'elemento che contiene un testo specifico e questo è ciò che mi è venuto in mente.

Utilizzare document.getElementsByInnerText() per ottenere più elementi (più elementi potrebbero avere lo stesso testo esatto) e utilizzare document.getElementByInnerText() per ottenere un solo elemento (prima corrispondenza).

Inoltre, è possibile localizzare la ricerca utilizzando un elemento (ad esempio someElement.getElementByInnerText()) anziché document.

Potrebbe essere necessario modificarlo per renderlo cross-browser o soddisfare le vostre esigenze.

Penso che il codice sia auto-esplicativo, quindi lo lascerò così com'è.

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>

Problemi correlati