जावास्क्रिप्ट .querySelector <div> को भीतर से खोजें


108

मैं कुछ पाठ के साथ DIV कैसे पा सकता हूं? उदाहरण के लिए:

<div>
SomeText, text continues.
</div>

कुछ इस तरह का उपयोग करने की कोशिश कर रहा है:

var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);

लेकिन संभोग से यह नहीं चलेगा। मैं यह कैसे कर सकता हूं?


यहां तक ​​कि अगर आप ऐसा कर सकते हैं, तो यह सभी डीवी प्राप्त करने और उन्हें इनरटेक्स्ट संपत्ति पर फ़िल्टर करने की तुलना में कोई तेज़ नहीं होगा। तो आप इसे मैन्युअल रूप से क्यों नहीं करते हैं।
रेडू

जवाबों:


100

ओपी का प्रश्न सादे जावास्क्रिप्ट के बारे में है न कि jQuery के बारे में । हालाँकि इसके बहुत सारे उत्तर हैं और मुझे @ पवन नोगरिया का जवाब पसंद है , कृपया इस विकल्प को देखें।

आप जावास्क्रिप्ट में XPATH का उपयोग कर सकते हैं । एमडीएन लेख पर अधिक जानकारी यहां

document.evaluate()विधि एक XPath क्वेरी / अभिव्यक्ति मूल्यांकन करता है। तो आप वहाँ XPATH अभिव्यक्तियों को पारित कर सकते हैं, HTML दस्तावेज़ में पार कर सकते हैं और वांछित तत्व का पता लगा सकते हैं।

XPATH में आप निम्न की तरह पाठ नोड द्वारा एक तत्व का चयन कर सकते हैं, जो divकि निम्नलिखित पाठ नोड है।

//div[text()="Hello World"]

एक तत्व प्राप्त करने के लिए जिसमें कुछ पाठ शामिल हैं, निम्नलिखित हैं:

//div[contains(., 'Hello')]

contains()XPATH में विधि पहले पैरामीटर और पाठ दूसरा पैरामीटर के रूप में के लिए खोज करने के रूप में एक नोड लेता है।

इस प्लंक को यहां चेक करें , यह जावास्क्रिप्ट में XPATH का एक उदाहरण है

यहाँ एक कोड स्निपेट है:

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

जैसा कि आप देख सकते हैं, मैं HTML तत्व को पकड़ सकता हूं और इसे संशोधित कर सकता हूं जैसा मैं चाहता हूं।


धन्यवाद! बहुत अच्छा काम करता है! लेकिन अगर मुझे इस पाठ से केवल एक शब्द को हथियाने की आवश्यकता है, तो "thisHeading.textContent" को "कंसोल.लॉग" कैसे करें? उदाहरण के लिए: '// div [शामिल (, \।' / आप लॉग इन (*) बार इस सत्र / \। ')]' और फिर चेतावनी (thisHeading.textContent $ 1।)
पासवर्ड

ठीक है, मैं इसे इस तरह से करता हूं:alert(thisHeading.textContent.replace(/.*You have login (.*) times.*/,'$1')) ;
8:09

@passwd, अच्छी तरह से आप ऐसा नहीं कर सकते। XPATH 1.0 में रेगेक्स का समर्थन नहीं किया गया है (जो .evaluate()उपयोग करता है। कृपया किसी ने मुझे गलत होने पर सही करें), इसलिए सबसे पहले, आप एक ऐसी चीज की खोज नहीं कर सकते हैं जो एक नियमित अभिव्यक्ति से मेल खाती हो। दूसरे, .textContentसंपत्ति तत्व का पाठ नोड लौटाती है। यदि आप इस पाठ से एक मूल्य पकड़ना चाहते हैं, तो आपको इसे स्पष्ट रूप से संभालना चाहिए, शायद कुछ प्रकार के फ़ंक्शन बनाकर जो एक रेगेक्स से मेल खाता है और समूह में मिलान मूल्य लौटाता है। इसके लिए एक अलग थ्रेड पर एक नया प्रश्न बनाते हैं।
गदर्राइटिस

इंटरनेट एक्सप्लोरर: कोई समर्थन नहीं। लेकिन एज में सपोर्ट किया। मुझे यकीन नहीं है कि इसका क्या मतलब है, संस्करण-वार।
रॉल्फ

यदि मैं जिस तत्व की तलाश कर रहा हूं, वह गायब होने की स्थिति में एक त्रुटि को कैसे नियंत्रित किया जाना चाहिए?
nenito

72

आप इस सरल समाधान का उपयोग कर सकते हैं:

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
  1. Array.fromएक सरणी के लिए NodeList में परिवर्तित कर देंगे (वहाँ प्रसार ऑपरेटर या टुकड़ा की तरह यह करने के लिए कई तरीके हैं)

  2. परिणाम अब एक सरणी Array.findविधि का उपयोग करने के लिए अनुमति देता है , तो आप किसी भी विधेय में डाल सकते हैं। तुम भी एक regex या आप की तरह के साथ textContent की जाँच कर सकते हैं।

ध्यान दें कि Array.fromऔर Array.findES2015 विशेषताएं हैं। एक ट्रांसपिलर के बिना IE10 जैसे पुराने ब्राउज़रों के साथ संगत होना चाहिए:

Array.prototype.slice.call(document.querySelectorAll('div'))
  .filter(function (el) {
    return el.textContent === 'SomeText, text continues.'
  })[0];

2
यदि आप कई तत्वों को खोजना चाहते हैं, तो findसाथ बदलें filter
रुबेलडाईकेजेट

38

चूंकि आपने इसे जावास्क्रिप्ट में पूछा है, इसलिए आपके पास ऐसा कुछ हो सकता है

function contains(selector, text) {
  var elements = document.querySelectorAll(selector);
  return Array.prototype.filter.call(elements, function(element){
    return RegExp(text).test(element.textContent);
  });
}

और फिर इसे इस तरह से कॉल करें

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

1
इस काम करता है की तरह लगता है, लेकिन बदले में मैं केवल यह हो रही है:[object HTMLDivElement],[object HTMLDivElement]
पासवर्ड

हाँ, आपको इसमें मिलान पाठ के साथ divs मिल रहे हैं और फिर आप वहाँ आंतरिक पाठ विधि को कुछ इस तरह से कह सकते हैं foundDivs[0].innerText, वह सरल है
पवन नोगरिया

20

यह समाधान निम्न कार्य करता है:

  • ES6 स्प्रेड ऑपरेटर का उपयोग करके सभी divs के NodeList को एक अरै में परिवर्तित करता है ।

  • अगर क्वेरी स्ट्रिंग div समाहित करता है, तो आउटपुट प्रदान करता है , न कि यदि यह बिल्कुल क्वेरी स्ट्रिंग (जो अन्य उत्तरों में से कुछ के लिए होता है) के बराबर होता है। उदा। यह न केवल 'SomeText' के लिए बल्कि 'SomeText, पाठ जारी है' के लिए आउटपुट प्रदान करना चाहिए।

  • संपूर्ण divसामग्री को आउटपुट करता है , न कि केवल क्वेरी स्ट्रिंग को। उदाहरण के लिए 'कुछटैक्स्ट, पाठ जारी है' यह उस पूरे स्ट्रिंग को आउटपुट करना चाहिए, न कि केवल 'कुछ टेक्स्ट' को।

  • एकाधिक divएस के लिए स्ट्रिंग को शामिल करने की अनुमति देता है , न कि केवल एक div

[...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>


3
मुझे यह पसंद है। साफ, संक्षिप्त और समझदार - सभी एक ही समय में।
ba_ul

2
बुरी तरह से अक्षम? सोचें कि innerHTMLआपके टॉप-मोस्ट के लिए कितना बड़ा है <div>। आपको divपहले बच्चों को फ़िल्टर करना चाहिए । इसके अलावा शक और document.getElementsByTagName('div')तेज़ हो सकता है लेकिन मैं निश्चित होना चाहूँगा।
टिम्मम

यह मेरे लिए बहुत अच्छा है, मैं
भीख मांगने के

10

आप सबसे अच्छा देखते हैं कि क्या आपके पास उस div का मूल तत्व है जिसे आप क्वेरी कर रहे हैं। यदि ऐसा है तो मूल तत्व प्राप्त करें और प्रदर्शन करें element.querySelectorAll("div")। एक बार जब आप संपत्ति nodeListपर इस पर एक फिल्टर लागू करते innerTextहैं। मान लें कि जिस div का हम क्वेरी कर रहे हैं उसका मूल तत्व a idहै container। आप आम तौर पर आईडी से सीधे कंटेनर तक पहुंच सकते हैं लेकिन चलो इसे उचित तरीके से करते हैं।

var conty = document.getElementById("container"),
     divs = conty.querySelectorAll("div"),
    myDiv = [...divs].filter(e => e.innerText == "SomeText");

तो यह बात है।


इसने मेरे लिए काम किया लेकिन इनरएचटीएमएल के बजाय इनरएचटीएमएल के साथ
चेस सैंडमैन

5

यदि आप jquery या उस जैसे कुछ का उपयोग नहीं करना चाहते हैं तो आप यह कोशिश कर सकते हैं:

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]
} 

एक बार जब आपके पास एक सरणी में नोड्स होते हैं जिसमें पाठ होता है तो आप उनके साथ कुछ कर सकते हैं। जैसे हर एक को सचेत करना या सांत्वना देना प्रिंट करना। एक चेतावनी यह है कि यह जरूरी नहीं है कि आप प्रति सेगमेंट को पकड़ सकें, यह उस टेक्स्टन के अभिभावक को हड़प लेगा जिसके पास वह पाठ है जिसकी आप तलाश कर रहे हैं।


3

चूंकि डेटा विशेषता में पाठ की लंबाई की कोई सीमा नहीं है, इसलिए डेटा विशेषताओं का उपयोग करें! और फिर आप अपने तत्व (ओं) का चयन करने के लिए नियमित सीएसएस चयनकर्ताओं का उपयोग कर सकते हैं जैसे ओपी चाहता है।

for (const element of document.querySelectorAll("*")) {
  element.dataset.myInnerText = element.innerText;
}

document.querySelector("*[data-my-inner-text='Different text.']").style.color="blue";
<div>SomeText, text continues.</div>
<div>Different text.</div>

आदर्श रूप से आप दस्तावेज़ लोड पर डेटा विशेषता सेटिंग भाग करते हैं और प्रदर्शन के लिए querySelectorAll चयनकर्ता को थोड़ा संकीर्ण करते हैं।


2

Google के लिए यह एक शीर्ष परिणाम के रूप में उन लोगों के लिए है जिन्हें कुछ पाठ के साथ नोड खोजने की आवश्यकता है। अद्यतन के माध्यम से, एक नोडेलिस्ट आधुनिक ब्राउज़र में अब इसे बिना किसी सरणी में परिवर्तित किए चलने योग्य है।

समाधान इस तरह से forEach का उपयोग कर सकता है।

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
    }
});

यह मेरे लिए एक नोडलिस्ट के अंदर एक पाठ को खोजने / बदलने का काम करता है जब एक सामान्य चयनकर्ता सिर्फ एक नोड का चयन नहीं कर सकता था, इसलिए मुझे सुई के लिए इसे जांचने के लिए प्रत्येक नोड को एक-एक करके फ़िल्टर करना होगा।


2

XPath और document.ev मूल्यांकन () का उपयोग करें, और पाठ का उपयोग करना सुनिश्चित करें () और नहीं। सम्‍मिलित () तर्क के लिए, वरना आपके पास संपूर्ण HTML, या बाहरी div तत्व का मिलान होगा।

var headings = document.evaluate("//h1[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

या व्हाट्सएप के प्रमुख और अनुगामी को अनदेखा करें

var headings = document.evaluate("//h1[contains(normalize-space(text()), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

या सभी टैग प्रकारों का मिलान करें (div, h1, p, आदि)

var headings = document.evaluate("//*[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

फिर पुनरावृति

let thisHeading;
while(thisHeading = headings.iterateNext()){
    // thisHeading contains matched node
}

क्या इस विधि का उपयोग किसी तत्व में एक वर्ग जोड़ने के लिए किया जा सकता है? जैसेthisheading.setAttribute('class', "esubject")
मैथ्यू

एक बार जब आप तत्व है, निश्चित रूप से। हालांकि, यह element.classList.add ( "esubject"), हालांकि :) का उपयोग करने के लिए बेहतर है
स्टीवन Spungin

1

यहाँ XPath दृष्टिकोण है लेकिन XPath शब्दजाल की एक न्यूनतम के साथ।

तत्व विशेषता मूल्यों (तुलना के लिए) के आधार पर नियमित चयन:

// for matching <element class="foo bar baz">...</element> by 'bar'
var things = document.querySelectorAll('[class*="bar"]');
for (var i = 0; i < things.length; i++) {
    things[i].style.outline = '1px solid red';
}

XPath चयन तत्व के भीतर पाठ पर आधारित है।

// for matching <element>foo bar baz</element> by 'bar'
var things = document.evaluate('//*[contains(text(),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
    things.snapshotItem(i).style.outline = '1px solid red';
}

और यहाँ मामला असंवेदनशीलता के साथ है क्योंकि पाठ अधिक अस्थिर है:

// for matching <element>foo bar baz</element> by 'bar' case-insensitively
var things = document.evaluate('//*[contains(translate(text(),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
    things.snapshotItem(i).style.outline = '1px solid red';
}

0

मुझे भी ऐसी ही समस्या थी।

फ़ंक्शन जो सभी तत्व वापस करता है जिसमें arg से पाठ शामिल है।

यह मेरे लिए काम करता है:

function getElementsByText(document, str, tag = '*') {
return [...document.querySelectorAll(tag)]
    .filter(
        el => (el.text && el.text.includes(str))
            || (el.children.length === 0 && el.outerText && el.outerText.includes(str)))

}


0

यहां पहले से ही बहुत सारे शानदार समाधान हैं। हालाँकि, एक अधिक सुव्यवस्थित समाधान प्रदान करने के लिए और एक क्वेरीसेलेक्टर व्यवहार और वाक्यविन्यास के विचार को ध्यान में रखते हुए, मैंने एक समाधान के लिए चुना जो ऑब्जेक्ट को कुछ प्रोटोटाइप फ़ंक्शन के साथ विस्तारित करता है। ये दोनों फ़ंक्शन मिलान पाठ के लिए नियमित अभिव्यक्तियों का उपयोग करते हैं, हालांकि, एक स्ट्रिंग को एक ढीले खोज पैरामीटर के रूप में प्रदान किया जा सकता है।

बस निम्नलिखित कार्यों को लागू करें:

// find all elements with inner text matching a given regular expression
// args: 
//      selector: string query selector to use for identifying elements on which we 
//                should check innerText
//      regex: A regular expression for matching innerText; if a string is provided,
//             a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerTextAll = function(selector, regex) {
    if (typeof(regex) === 'string') regex = new RegExp(regex, 'i'); 
    const elements = [...this.querySelectorAll(selector)];
    const rtn = elements.filter((e)=>{
        return e.innerText.match(regex);
    });
    
    return rtn.length === 0 ? null : rtn
}

// find the first element with inner text matching a given regular expression
// args: 
//      selector: string query selector to use for identifying elements on which we 
//                should check innerText
//      regex: A regular expression for matching innerText; if a string is provided,
//             a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerText = function(selector, text){
    return this.queryInnerTextAll(selector, text)[0];
}

लागू किए गए इन कार्यों के साथ, आप अब निम्नानुसार कॉल कर सकते हैं:

  • document.queryInnerTextAll('div.link', 'go');
    यह सभी divs को लिंक वर्ग से युक्त मिलेगा , जो इनरटेक्स्ट में जाने वाले शब्द के साथ है (उदाहरण के लिए। बाएँ जाएँ या नीचे जाएँ या दाएँ जाएँ या इट्स गो ओड )
  • document.queryInnerText('div.link', 'go');
    यह ठीक ऊपर के उदाहरण के रूप में काम करेगा सिवाय इसके कि यह केवल पहले मिलान तत्व को लौटाएगा।
  • document.queryInnerTextAll('a', /^Next$/);
    सटीक टेक्स्ट के साथ सभी लिंक खोजें अगला (केस-सेंसिटिव)। यह उन लिंक को बाहर कर देगा, जिनमें अगला शब्द अन्य पाठ के साथ है।
  • document.queryInnerText('a', /next/i);
    पहली कड़ी है कि शब्द है का पता लगाएं अगले , मामले की परवाह किए बिना (जैसे। अगला पृष्ठ या अगले पर जाएं )
  • e = document.querySelector('#page');
    e.queryInnerText('button', /Continue/);
    यह पाठ वाले बटन के लिए एक कंटेनर तत्व के भीतर एक खोज करता है, जारी रखें (केस-संवेदी)। (उदाहरण। जारी रखें या आगे जारी रखें लेकिन जारी नहीं रखें )
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.