web-dev-qa-db-ja.com

Javascript .querySelector find <div> by innerTEXT

特定のテキストでDIVを見つけるにはどうすればよいですか?例えば:

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

このようなものを使用しようとしています:

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

しかし、もちろん機能しません。どうすればいいですか?

58
passwd

OPの質問はプレーンJavaScriptであり、jQueryではありません。たくさんの答えがあり、@ Pawan Nogariyaの答えが好きですが、この代替案をチェックしてください。

JavaScriptでXPATHを使用できます。 MDNの記事に関する詳細情報 こちら

document.evaluate()メソッドは、XPATHクエリ/式を評価します。したがって、XPATH式をそこに渡し、HTMLドキュメントを走査して、目的の要素を見つけることができます。

XPATHでは、次のようなテキストノードによって、次のテキストノードを持つdivを取得する要素を選択できます。

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

テキストを含む要素を取得するには、次を使用します。

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

XPATHのcontains()メソッドは、最初のパラメーターとしてノードを取り、2番目のパラメーターとして検索するテキストを取ります。

このプランクを確認してください here 、これはJavaScriptでの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要素を取得して、好きなように変更できます。

58
gdyrrahitis

あなたはjavascriptでそれを尋ねたので、あなたはこのようなものを持つことができます

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
28
Pawan Nogariya

この非常にシンプルなソリューションを使用できます。

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
  1. Array.fromはNodeListを配列に変換します(これを行うには、スプレッド演算子またはスライスのような複数のメソッドがあります)

  2. 結果は配列になったため、Array.findメソッドを使用できるようになり、任意の述語を入れることができます。また、正規表現などを使用してtextContentを確認することもできます。

Array.fromArray.findはES2015の機能であることに注意してください。トランスパイラーなしでIE10のような古いブラウザーと互換性があります。

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

このソリューションは次のことを行います。

  • ES6スプレッド演算子を使用して、すべてのdivsのNodeListを配列に変換します。

  • div含むクエリ文字列の場合に出力を提供します。正確に等しいクエリ文字列(他のいくつかの回答で発生します)だけではありません。例えば「SomeText」だけでなく「SomeText、text continue」にも出力を提供する必要があります。

  • クエリ文字列だけでなく、divコンテンツ全体を出力します。例えば「SomeText、text continue」の場合、「SomeText」だけでなく、文字列全体を出力する必要があります。

  • 単一の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>
10
Andrew Willems

照会しているdivの親要素があるかどうかを最もよく確認できます。その場合は、親要素を取得してelement.querySelectorAll("div")を実行します。 nodeListを取得したら、innerTextプロパティにフィルターを適用します。クエリしているdivの親要素のidcontainerであると仮定します。通常、idから直接コンテナにアクセスできますが、適切な方法でアクセスしてみましょう。

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

以上です。

5
Redu

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

テキストを含む配列内のノードを取得したら、それらを使用して何かを実行できます。各自に警告するか、コンソールに出力します。 1つの注意点は、これは必ずしもdiv自体を取得する必要はないかもしれないということです。これは、探しているテキストを持つtextnodeの親を取得します。

3
Steve Botello

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

これは、通常のセレクターがノードを1つだけ選択できない場合に、ノードリスト内でテキストの検索/置換を行うために機能しました。

0
Vigilante

XPathとdocument.evaluate()を使用し、ではなくtext()を使用するようにしてください。 contains()引数の場合、または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
}
0
Steven Spungin

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
Jan Kyu Peblik