জাভাস্ক্রিপ্ট। ক্যোয়ারী নির্বাচনকারীরা <<> ডিভোর্সটি টেক্সট দ্বারা সন্ধান করুন


116

আমি কীভাবে নির্দিষ্ট পাঠ্য সহ ডিআইভি খুঁজে পাব? উদাহরণ স্বরূপ:

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

এই জাতীয় কিছু ব্যবহার করার চেষ্টা করছেন:

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

তবে অবশ্যই এটি কাজ করবে না। আমি এটা কিভাবে করবো?


এমনকি যদি আপনি এটি করতে পারতেন তবে সমস্ত ডিভগুলি পাওয়ার এবং তাদের অভ্যন্তরীণ পাঠ্য সম্পত্তিতে ফিল্টার করার চেয়ে দ্রুত আর কিছু হবে না। সুতরাং কেন আপনি ম্যানুয়ালি এটি না।
রেডু

সম্ভাব্য সদৃশ:
জিকুয়ের

উত্তর:


108

ওপির প্রশ্নটি প্লেইন জাভাস্ক্রিপ্ট সম্পর্কিত এবং জিকুয়েরি নয় । যদিও প্রচুর উত্তর রয়েছে এবং আমি @ পবন নোগারিয়া উত্তর পছন্দ করি তবে দয়া করে এই বিকল্পটি দেখুন।

আপনি জাভাস্ক্রিপ্টে XPATH ব্যবহার করতে পারেন । MDN নিবন্ধ সম্পর্কে আরও তথ্য এখানে

document.evaluate()পদ্ধতি একটি XPath ক্যোয়ারী / মত প্রকাশের মূল্যায়ন করে। সুতরাং আপনি সেখানে এক্সপ্যাথ এক্সপ্রেশনগুলি পাস করতে পারেন, এইচটিএমএল ডকুমেন্টের মধ্যে যেতে পারেন এবং পছন্দসই উপাদানটি সনাক্ত করতে পারেন।

এক্সপ্যাথটিতে আপনি নীচের মতো পাঠ্য নোডের মাধ্যমে একটি উপাদান নির্বাচন করতে পারেন, divযা নীচের পাঠ্য নোডটি পেয়েছে।

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

কিছু পাঠ্য রয়েছে এমন একটি উপাদান পেতে নিম্নলিখিত ব্যবহার করুন:

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

contains()XPath পদ্ধতি প্রথম প্যারামিটার এবং টেক্সট দ্বিতীয় প্যারামিটার হিসাবে জন্য অনুসন্ধান করতে যেমন একটি নোড লাগে।

এই প্লাঙ্কটি এখানে দেখুন , এটি জাভাস্ক্রিপ্টে XPATH এর উদাহরণ use

এখানে একটি কোড স্নিপেট:

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

আপনি দেখতে পাচ্ছেন, আমি এইচটিএমএল উপাদানটি ধরতে পারি এবং এটি আমার পছন্দ মতো পরিবর্তন করতে পারি।


ধন্যবাদ! দুর্দান্ত কাজ! তবে এই পাঠ্য থেকে যদি আমার কেবল একটি শব্দ দখল করতে হয় তবে কীভাবে "কনসোল.লগ" "এই হিডিং.টেক্সট কনটেন্ট" করবেন? উদাহরণ হিসেবে বলা যায়: '// DIV আছে [ধারণ করে (, \।' / আপনাকে অবশ্যই প্রবেশ (*) বার এই সেশনের / \। ')]' এবং তারপর সতর্কতা (thisHeading.textContent $ 1।)
passwd কোন

: ঠিক আছে, আমি এটা এই ভাবে কি করতেalert(thisHeading.textContent.replace(/.*You have login (.*) times.*/,'$1')) ;
passwd কোন

@ পাসউড, ভাল আপনি এটি করতে পারবেন না। এক্সপিএটিএইচ 1.0 তে রেজেক্স সমর্থিত নয় (যা .evaluate()ব্যবহার করে Please দয়া করে কেউ আমার ভুল হলে আমাকে সংশোধন করে), তাই প্রথমত, আপনি এমন কোনও বিষয় সন্ধান করতে পারবেন না যা নিয়মিত প্রকাশের সাথে মেলে। দ্বিতীয়ত, .textContentসম্পত্তি উপাদানটির পাঠ্য নোড প্রদান করে। আপনি যদি এই পাঠ্যের কোনও মান ধরতে চান তবে আপনার স্পষ্টভাবে এটি পরিচালনা করা উচিত, সম্ভবত এমন কোনও ফাংশন তৈরি করে যা একটি রেজেক্সের সাথে মেলে এবং গ্রুপে ম্যাচের মানটি ফেরত দেয় For এজন্য একটি পৃথক থ্রেডে একটি নতুন প্রশ্ন করুন।
গিরিরাহাইটিস

ইন্টারনেট এক্সপ্লোরার: কোনও সমর্থন নেই। তবে এজ এ সাপোর্টড সংস্করণ অনুসারে এর অর্থ কী তা আমি নিশ্চিত নই।
রল্ফ

আমি যে উপাদানটির সন্ধান করছি তার অনুপস্থিত অবস্থায় কীভাবে একটি ত্রুটি সামলানো উচিত?
নেনিটো

76

আপনি এই খুব সহজ সমাধান ব্যবহার করতে পারেন:

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
  1. Array.fromএকটি অ্যারের NodeList রূপান্তর হবে (সেখানে বিস্তার অপারেটর বা ফালি মত এই কাজ করতে একাধিক পদ্ধতি)

  2. ফলাফলটি এখন অ্যারে হওয়ায় Array.findপদ্ধতিটি ব্যবহারের অনুমতি দেয় আপনি তারপরে যে কোনও প্রাকটিকেল রাখতে পারেন। আপনি একটি রেইজেক্স বা আপনি যা পছন্দ করেন তা দিয়ে টেক্সট কনটেন্টটিও পরীক্ষা করতে পারেন।

নোট করুন Array.fromএবং Array.findES2015 বৈশিষ্ট্য রয়েছে। কোনও ট্রান্সপোর্টার ছাড়াই IE10 এর মতো পুরানো ব্রাউজারগুলির সাথে সামঞ্জস্য থাকুন:

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

4
আপনি যদি একাধিক উপাদান সন্ধান করতে চান তবে এর findসাথে প্রতিস্থাপন করুন filter
রুবেলডিয়েকাটজ

41

যেহেতু আপনি এটি জাভাস্ক্রিপ্টে জিজ্ঞাসা করেছেন তাই আপনার এর মতো কিছু থাকতে পারে

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

4
এই কাজ মত মনে হয়, কিন্তু বিনিময়ে আমি শুধু এই হচ্ছি:[object HTMLDivElement],[object HTMLDivElement]
passwd কোন

হ্যাঁ আপনি এতে মেলানো পাঠ্যের সাথে ডিভগুলি পাচ্ছেন এবং তারপরে আপনি সেখানে অভ্যন্তরীণ পাঠ্য পদ্ধতিটিকে এমন কিছু foundDivs[0].innerTextসহজ, সহজ বলতে পারেন
পবন নোগারিয়া

21

এই সমাধানটি নিম্নলিখিতগুলি করে:

  • সকলের নোডলিস্টকে divএকটি অ্যারেতে রূপান্তর করতে ES6 স্প্রেড অপারেটর ব্যবহার করে ।

  • যদি কোয়েরি স্ট্রিং div থাকে তবে আউটপুট সরবরাহ করে , এটি ঠিক কোয়েরি স্ট্রিংয়ের সমান হয় না (যা অন্য কয়েকটি উত্তরের জন্য ঘটে)। উদাহরণস্বরূপ এটি কেবল 'সামারেক্সট'-এর জন্য নয়' সোমারটেক্সট, পাঠ্য অবিরত 'জন্য আউটপুট সরবরাহ করা উচিত।

  • 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>


4
আমি এটা ভালোবাসি. পরিষ্কার, সংক্ষিপ্ত এবং বোধগম্য - সব একই সময়ে।
বা_ুল

4
মারাত্মকভাবে অক্ষম? innerHTMLআপনার শীর্ষস্থানীয়দের জন্য কত বড় তা ভাবুন <div>। আপনার divপ্রথমে শিশু রয়েছে এমন ফিল্টার আউট করা উচিত । সন্দেহও document.getElementsByTagName('div')দ্রুত হতে পারে তবে আমি নিশ্চিত হয়ে বেঞ্চমার্ক করব।
টিম্ম্ম্ম

এটি আমার পক্ষে দুর্দান্ত, আমি শুরুতে একটি ভাল নির্বাচককে সেট করতে পারি কারণ আমি ইতিমধ্যে জানি যে এটি কেবল একটি টেবিলে থাকতে পারে, শীতল, ধন্যবাদ
gsalgadotoledo

11

আপনি দেখতে পাচ্ছেন যে ডিভের কোনও অভিভাবক উপাদান আপনি জিজ্ঞাসা করছেন তা আপনি দেখতে পারেন। যদি তাই হয় তবে মূল উপাদানটি পান এবং একটি সম্পাদন করুন element.querySelectorAll("div")। একবার আপনি সম্পত্তির nodeListউপরে এটিতে একটি ফিল্টার প্রয়োগ করুন innerText। ধরে নিন যে আমরা যে ডিভের জন্য জিজ্ঞাসা করছি তার একটি পিতামাতার উপাদানটির একটি 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>

আদর্শভাবে আপনি ডকুমেন্ট লোডে ডেটা অ্যাট্রিবিউট সেটিং অংশটি করেন এবং ক্যোয়ারী নির্বাচনকারী সমস্ত নির্বাচককে পারফরম্যান্সের জন্য কিছুটা সঙ্কুচিত করেন।


2

গুগলের এটির জন্য শীর্ষ ফলাফল হিসাবে যাঁদের নির্দিষ্ট পাঠ্য সহ নোডের সন্ধান দরকার। আপডেটের মাধ্যমে, কোনও নোডলিস্ট এখন আধুনিক ব্রাউজারগুলিতে অ্যারেতে রূপান্তর না করে পুনরাবৃত্তিযোগ্য।

সমাধান যেমন প্রতিটি জন্য ব্যবহার করতে পারেন।

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

এক্সপথ এবং ডকুমেন্ট.ইভ্যালুয়েট () ব্যবহার করুন এবং পাঠ্য () ব্যবহার করুন এবং না তা নিশ্চিত করুন। () আর্গুমেন্টের জন্য বা অন্যথায় আপনার কাছে পুরো এইচটিএমএল, বা বাইরেরতম ডিভ উপাদানটি মিলবে।

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

বা সমস্ত ট্যাগের সাথে (ডিভ, এইচ 1, পি, ইত্যাদি) মেলে

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")
ম্যাথিউ

একবার আপনার কাছে এলিমেন্ট থাকলে নিশ্চিত হয়ে নিন। তবে এলিমেন্ট.ক্লাসলিস্ট.এডডি ("এসবজেক্ট") ব্যবহার করা ভাল তবে :)
স্টিভেন স্পঞ্জিন

1

এখানে এক্সপথ পদ্ধতির তবে সর্বনিম্ন এক্সপথ জার্গন সহ।

উপাদান বৈশিষ্ট্যের মানগুলির তুলনায় নিয়মিত নির্বাচন (তুলনার জন্য):

// 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';
}

উপাদানটির মধ্যে পাঠ্যের উপর ভিত্তি করে এক্সপাথ নির্বাচন।

// 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

আমারও একই সমস্যা ছিল

ফাংশন যা সমস্ত উপাদানকে দেয় যা আর্গ থেকে পাঠ্য অন্তর্ভুক্ত করে।

এটি আমার পক্ষে কাজ করে:

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

ইতিমধ্যে এখানে প্রচুর দুর্দান্ত সমাধান রয়েছে। তবে আরও মসৃণ সমাধান প্রদান এবং এক একটি querySelector আচরণ এবং বাক্য গঠন ধারণা সঙ্গে পালন আরও, আমি একটি সমাধান প্রসারিত নির্বাচিত বস্তু একটি দম্পতি প্রোটোটাইপ ফাংশন সঙ্গে। এই দুটি ফাংশনই টেক্সটের সাথে মিলে যাওয়ার জন্য নিয়মিত এক্সপ্রেশন ব্যবহার করে তবে একটি স্ট্রিং looseিলে searchালা অনুসন্ধানের প্যারামিটার হিসাবে সরবরাহ করা যেতে পারে।

কেবল নিম্নলিখিত ফাংশনগুলি বাস্তবায়ন করুন:

// 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 ধারণকারী লিংক শব্দ দিয়ে বর্গ চলতে চলতে innerText মধ্যে (যেমন। বামে যান বা নামা বা সরাসরি যান বা এটা এর যান আদ্যাশক্তি )
  • document.queryInnerText('div.link', 'go');
    এটি কেবল প্রথম ম্যাচের উপাদানটি ফিরিয়ে এনে উপরের উদাহরণ হিসাবে ঠিক কাজ করবে।
  • document.queryInnerTextAll('a', /^Next$/);
    পরবর্তী পাঠ্য (কেস-সংবেদনশীল) সহ সমস্ত লিঙ্কগুলি সন্ধান করুন । এটি অন্যান্য পাঠ্যের পাশাপাশি নেক্সট শব্দটি যুক্ত লিঙ্কগুলিকে বাদ দেবে ।
  • document.queryInnerText('a', /next/i);
    পরের শব্দটি সম্বলিত প্রথম লিঙ্কটি সন্ধান করুন , ক্ষেত্রে নির্বিশেষে (উদাঃ পরবর্তী পৃষ্ঠা বা পরের দিকে যান )
  • e = document.querySelector('#page');
    e.queryInnerText('button', /Continue/);
    এটি চালিয়ে (কেস-সংবেদনশীল) পাঠ্যযুক্ত বোতামটির জন্য ধারক উপাদানটির মধ্যে অনুসন্ধান চালায় । (যেমন। চালিয়ে বা পরবর্তী চালিয়ে যাও কিন্তু না অবিরত )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.