2010-09-28 47 views

Respuesta

65

Vas a tener que atravesar con la 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 Actualmente innerHTML es estándar. innerText no funciona en FF – AnaMaria

+0

Actualizado el ejemplo, textContent es probable que lo que desea en este caso. Gracias, amigos :) –

+1

@AugustLilleaas, ¿qué pasa con el 'i

0

Si bien es posible pasar por el texto interior, creo que te estás dirigiendo por el camino equivocado. Es esa cadena interna generada dinámicamente? Si es así, puede darle una clase a la etiqueta o, mejor aún, una ID cuando ingrese el texto. Si es estático, entonces es aún más fácil.

0

Creo que tendrá que ser un poco más específico para ayudarlo.

  1. ¿Cómo es esto? Javascript? PHP? Perl?
  2. ¿Se puede aplicar un atributo de ID a la etiqueta?

Si el texto es único (o realmente, si no lo es, pero tendría que ejecutar una matriz) podría ejecutar una expresión regular para encontrarlo. El uso de preg_match() de PHP funcionaría para eso.

Si está utilizando Javascript y puede insertar un atributo de identificación, puede usar getElementById ('id'). A continuación, puede acceder a los atributos del elemento devuelto a través del DOM: https://developer.mozilla.org/en/DOM/element.1.

14

Mientras que ha sido desde hace bastante tiempo, y que ya ha (a largo ya) aceptó una respuesta, pensé que ofrecería un enfoque actualizado:

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>

Por supuesto , de una manera algo más simple todavía es:

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>

Referencias:

33

Usted podría utilizar XPath para lograr esto

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

También puede buscar de un elemento que contiene un texto que utiliza este XPath:

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

Esta debería ser la respuesta principal. XPath puede hacer mucho más, como seleccionar nodo por valor de atributo, seleccionar conjuntos de nodos ... Introducción simple: https://www.w3schools.com/xml/xpath_syntax.asp – Timathon

+0

Simple, elegante y avanzado. La mejor respuesta. –

+0

La pregunta es, ¿cuál es la penalización de rendimiento para este truco – vsync

9

Usando la sintaxis más moderna a vailable en este momento, se puede hacer de forma muy limpia así:

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

o con un filtro separado:

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

Naturalmente, navegadores antiguos no va a manejar esto, pero se puede utilizar un transpiler si se necesita soporte heredado.

1

Encontré el uso de la sintaxis más nueva un poco más corta en comparación con la respuesta de los demás. Así que aquí está mi propuesta:

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

enfoque funcional. Devuelve una matriz de todos los elementos coincidentes y recorta los espacios durante la comprobación.

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

si usted está buscando a través de diferentes etiquetas, es decir, lapso o el botón

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

El valor predeterminado tag = 'a' tendrá Babel para navegadores antiguos

-2

jQuery versión:

 

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

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

-1

Acabo de necesitar una forma de obtener el elemento que contiene un texto específico y esto es lo que se me ocurrió.

Usa document.getElementsByInnerText() para obtener elementos múltiples (varios elementos pueden tener el mismo texto exacto), y usa document.getElementByInnerText() para obtener solo un elemento (primera coincidencia).

Además, puede localizar la búsqueda utilizando un elemento (por ejemplo, someElement.getElementByInnerText()) en lugar de document.

Es posible que tenga que modificarlo para hacerlo entre navegadores o satisfacer sus necesidades.

Creo que el código se explica por sí mismo, así que lo dejo tal como está.

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>

Cuestiones relacionadas