
[code]

    <table>
    <tr><td>AAA</td></tr>
    <tr><td>BBB</td></tr>
    </table>
    
[/code]

というHTMLがあったとして、

jQueryで

[code]

    $("*:contains('AAA')").addClass('hoge');
    
[/code]

とした場合、先祖要素含めて「AAA」のテキストを内包する要素全てにクラスが付与され

[code]

    <table class="hoge">
    <tr class="hoge"><td class="hoge">AAA</td></tr>
    <tr><td>BBB</td></tr>
    </table>
    
[/code]

となってしまいます。（仕様通りの挙動）

恐らく素のJavascriptの処理的には

[code]

    const elements = document.querySelectorAll('*');
    const filterElements = Array.from(elements).filter((element)=> element.textContent.indexOf('AAA') !== -1);
    for(el of filterElements){
        el.classList.add('hoge');
    }
    
[/code]

と同じような感じなのかなと思うのですが、  
これを直近の要素だけ選択させることは可能でしょうか。

以下のようになっていてほしい：

[code]

    <table>
    <tr><td class="hoge">AAA</td></tr>
    <tr><td>BBB</td></tr>
    </table>
    
[/code]

解決策の一つとして

[code]

    $("*:contains('AAA'):not(:has(>*))").addClass('hoge');
    
[/code]

でも近いことはできたのですが、  
この場合、

[code]

    <table>
    <tr><td><br>AAA</td></tr>
    <tr><td>BBB</td></tr>
    </table>
    
[/code]

など、別の要素が入っているとうまく機能しません。


CC BY-SA 4.0
2022-12-18T05:54:07.863
92864
2022-12-18T23:34:44.023
2022-12-18T06:44:32.123
11153
11153
question
javascript jquery
jQueryで*:contains('AAA')セレクタで要素を選択させた際に直近の要素のみを選択できるようにしたい


[`:contains()`](https://api.jquery.com/contains-selector/)の説明には

> The matching text can appear directly within the selected element, in any of
> that element's descendants, or a combination thereof.

とあるように、子孫すべてのtext
nodeを対象に検索されるという点は仕様として受け入れざるを得ないかと。質問文でも検討されていますが、何等か別の条件付けをする他ありません。

簡単に思い付く方法として例えば`<TD>`タグに限定するのであれば

[code]

    $("td:contains('AAA')").addClass('hoge');
    
[/code]

とすれば、`<TABLE>`や`<TR>`にはマッチすることはなくなります。

その他、例えば、子ノードを調査して否定するとか。（コードは試していません。）

[code]

    $(":contains('AAA'):not(:has(> :contains('AAA')))").addClass('hoge');
    
[/code]

ただし、

[code]

    <div>
      AAA
      <p>AAA</p>
    </div>
    
[/code]

の場合に、外側の`<DIV>`まで否定されてしまう副作用があります。


CC BY-SA 4.0
2022-12-18T23:34:44.023
92886
2022-12-18T23:34:44.023
4236
92864
answer