obtener - Javascript.querySelector encuentra<div> por innerTEXT
queryselector value (8)
¿Cómo puedo encontrar DIV con cierto texto? Por ejemplo:
<div>
SomeText, text continues.
</div>
Intentando usar algo como esto:
var text = document.querySelector(''div[SomeText*]'').innerTEXT;
alert(text);
Pero, por supuesto, no funcionará. ¿Cómo puedo hacerlo?
Como lo ha pedido en JavaScript, puede tener algo como esto
function contains(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.filter.call(elements, function(element){
return RegExp(text).test(element.textContent);
});
}
Y luego llámalo así
contains(''div'', ''sometext''); // find "div" that contain "sometext"
contains(''div'', /^sometext/); // find "div" that start with "sometext"
contains(''div'', /sometext$/i); // find "div" that end with "sometext", case-insensitive
Esta solución hace lo siguiente:
-
Utiliza el operador de propagación ES6 para convertir la NodeList de todos los
div
s en una matriz. -
Proporciona resultados si el
div
contiene la cadena de consulta, no solo si es exactamente igual a la cadena de consulta (lo que ocurre para algunas de las otras respuestas). por ejemplo, debe proporcionar resultados no solo para ''SomeText'' sino también para ''SomeText, text text''. -
Emite todo el contenido
div
, no solo la cadena de consulta. Por ejemplo, para ''SomeText, el texto continúa'', debería generar esa cadena completa, no solo ''SomeText''. -
Permite que múltiples
div
contengan la cadena, no solo undiv
.
[...document.querySelectorAll(''div'')] // get all the divs in an array
.map(div => div.innerHTML) // get their contents
.filter(txt => txt.includes(''SomeText'')) // keep only those containing the query
.forEach(txt => console.log(txt)); // output the entire contents of those
<div>SomeText, text continues.</div>
<div>Not in this div.</div>
<div>Here is more SomeText.</div>
Google tiene esto como un resultado superior para Para aquellos que necesitan encontrar un nodo con cierto texto. A modo de actualización, una lista de nodos ahora es iterable en los navegadores modernos sin tener que convertirla en una matriz.
La solución se puede usar para cada uno así.
var elList = document.querySelectorAll(".some .selector");
elList.forEach(function(el) {
if (el.innerHTML.indexOf("needle") !== -1) {
// Do what you like with el
// The needle is case sensitive
}
});
Esto funcionó para mí para hacer un texto de búsqueda / reemplazo dentro de una lista de nodos cuando un selector normal no podía elegir solo un nodo, por lo que tuve que filtrar cada nodo uno por uno para verificar la aguja.
La pregunta de OP es sobre JavaScript simple y no sobre jQuery . Aunque hay muchas respuestas y me gusta la respuesta de @Pawan Nogariya, compruebe esta alternativa.
Puede usar XPATH en JavaScript. Más información sobre el artículo de MDN here .
El método
document.evaluate()
evalúa una consulta / expresión XPATH.
Entonces puede pasar expresiones XPATH allí, atravesar el documento HTML y ubicar el elemento deseado.
En XPATH puede seleccionar un elemento, por el nodo de texto como el siguiente, que obtiene el
div
que tiene el siguiente nodo de texto.
//div[text()="Hello World"]
Para obtener un elemento que contiene texto, use lo siguiente:
//div[contains(., ''Hello'')]
El método
contains()
en XPATH toma un nodo como primer parámetro y el texto para buscar como segundo parámetro.
Verifique este plunk here , este es un ejemplo de uso de XPATH en JavaScript
Aquí hay un fragmento de código:
var headings = document.evaluate("//h1[contains(., ''Hello'')]", document, null, XPathResult.ANY_TYPE, null );
var thisHeading = headings.iterateNext();
console.log(thisHeading); // Prints the html element in console
console.log(thisHeading.textContent); // prints the text content in console
thisHeading.innerHTML += "<br />Modified contents";
Como puede ver, puedo tomar el elemento HTML y modificarlo a mi gusto.
Lo mejor es ver si tiene un elemento padre del div que está consultando.
Si es así, obtenga el elemento padre y realice un
element.querySelectorAll("div")
.
Una vez que obtenga la lista de
nodeList
aplique un filtro sobre la propiedad
innerText
.
Suponga que un elemento padre del div que estamos consultando tiene una
id
de
container
.
Normalmente puede acceder al contenedor directamente desde la identificación, pero hagámoslo de la manera correcta.
var conty = document.getElementById("container"),
divs = conty.querySelectorAll("div"),
myDiv = [...divs].filter(e => e.innerText == "SomeText");
Eso es todo.
Podrías usar esta solución bastante simple:
Array.from(document.querySelectorAll(''div''))
.find(el => el.textContent === ''SomeText, text continues.'');
-
Array.from
convertirá la NodeList en una matriz (hay varios métodos para hacer esto, como el operador de propagación o la división) -
El resultado ahora es una matriz que permite usar el método
Array.find
, luego puede poner cualquier predicado. También puede verificar el contenido del texto con una expresión regular o lo que desee.
Tenga en cuenta que
Array.from
y
Array.find
son características de ES2015.
Ser compatible con navegadores antiguos como IE10 sin un transpiler:
Array.prototype.slice.call(document.querySelectorAll(''div''))
.filter(function (el) {
return el.textContent === ''SomeText, text continues.''
})[0];
Si no quieres usar jquery o algo así, puedes intentar esto:
function findByText(rootElement, text){
var filter = {
acceptNode: function(node){
// look for nodes that are text_nodes and include the following string.
if(node.nodeType === document.TEXT_NODE && node.nodeValue.includes(text)){
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
}
var nodes = [];
var walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, filter, false);
while(walker.nextNode()){
//give me the element containing the node
nodes.push(walker.currentNode.parentNode);
}
return nodes;
}
//call it like
var nodes = findByText(document.body,''SomeText'');
//then do what you will with nodes[];
for(var i = 0; i < nodes.length; i++){
//do something with nodes[i]
}
Una vez que tenga los nodos en una matriz que contiene el texto, puede hacer algo con ellos. Como alertar a cada uno o imprimir en la consola. Una advertencia es que esto puede no necesariamente tomar divs per se, esto tomará el padre del nodo de texto que tiene el texto que está buscando.
Use XPath y document.evaluate (), y asegúrese de usar text () y no. para el argumento contiene (), o de lo contrario tendrá el HTML completo o el elemento div más externo emparejado.
var headings = document.evaluate("//h1[contains(text(), ''Hello'')]", document, null, XPathResult.ANY_TYPE, null );
o ignorar espacios en blanco iniciales y finales
var headings = document.evaluate("//h1[contains(normalize-space(text()), ''Hello'')]", document, null, XPathResult.ANY_TYPE, null );
o hacer coincidir todos los tipos de etiquetas (div, h1, p, etc.)
var headings = document.evaluate("//*[contains(text(), ''Hello'')]", document, null, XPathResult.ANY_TYPE, null );
Luego iterar
let thisHeading;
while(thisHeading = headings.iterateNext()){
// thisHeading contains matched node
}