Developer

【Salesforce】LWCでIdを使ってセレクタするとハマった話

Developer
この記事は約4分で読めます。

こんにちは、アンダーソンです。
昨日とあるツイートをしたら、何件か返答をいただきとても勉強になったので、
そのことを記事にまとめておきたいと思います。
該当のツイートがこちら。

ツイートしたように、id指定すると謎の『-160』が付属され、
querySelectorで取れないということが判明。

単純にJavaScriptの勉強もかねてquerySelectorでいろいろ取って
試してただけなんですが、どうしてもId指定では取れずよく見ると
『-160』がついていてなんだこれ?と思いツイートしました。

それに対して何件かコメントいただいたので、その内容を実際に試していきます。

スポンサーリンク

直接アクセスはあきらめる

まずは、

そもそも非推奨なことなので、諦めるという方法です。
いやそれじゃ指定のものをとる時にはどうするのって感じなんですが。。
下記を例に試してみました。

<template>
    <lightning-card>
        <p>テスト1</p>
        <p>テスト2</p>
        <p>テスト3</p>
        <lightning-button label="確認" onclick={Confirm}></lightning-button>
    </lightning-card>
</template>
import { LightningElement } from 'lwc';

export default class SelectorTest extends LightningElement {

    Confirm(){
        const elem = this.template.querySelector('p').outerText;
        console.log(elem);
    }
}

単純にp要素の中のテキストを取得するだけなんですが、
3つ並んだ状態だとどうなるのかを試してみました。

結果は・・・

一番上の要素を取得するんですね。
ちなみに何度やっても一番上の要素を取得しました。(4回試しました笑)

指定の要素をとるのは諦めた方がいいのかもしれませんが、
一応できなくはないのでやってみましょう。

data-idを指定する

こちらいただいたツイートの通り、data-idで取得してみようと思います。
先ほどのp要素の二つ目を変更して

<p data-id="test">テスト2</p>

JavaScriptの方は、

const elem = this.template.querySelector('p[data-id=\'test\']').outerText;

こんな感じにしてみました。
これで実行してみると。。。

取れました。
ただちょっと冗長になってしまうとのお言葉通り、
セレクタ側が少し面倒な気もします。

クラスを指定する

次にこちらのツイートですね。
idではなくclassでと言うことで、LWCでもclass指定が問題なくできるか
念のためやってみました。
先ほどの3つめのp要素をまた書き換えました。

<p class="classTest">テスト3</p>

JavaScriptの方はセレクタの中を変えるだけですね。

const elem = this.template.querySelector('.classTest').outerText;

では実行結果をみてみます。

問題なく取れています。

まとめ

今回の件を調査していたところ公式ドキュメントでも出ていました。

テンプレートを表示するときに、id 値が、グローバル一意値に変換される場合があります。CSS または JavaScript で id セレクタを使用しないでください。変換された id に一致しなくなります。代わりに、要素の class 属性または data-* 属性 (data-id など) を使用してください。

コンポーネントアクセシビリティ属性

結論としては

  • 直接のアクセスは非推奨
  • idの指定をするとユニークの値に変換される
  • セレクタを使用してアクセスするなら、classもしくはdata-*を使う

ということのようです。
まだまだ知らないことだらけです。本当に。
これからもいろいろと試していきたいと思います!

その他の開発に関する記事はこちらです。

Developerも含めた試験問題にチャレンジしてみましょう。