1 of 32

その要素は本当に「見えている」のか�〜要素の “visibility” に関する考察〜

はじまるよ〜!

2 of 32

この資料を読んで下さる方へ

  • この資料を無断で二次利用(転載、流用、コピーなどなど)することはなしでお願いします🙇
  • この資料は第1回3rdparty.jsでの発表に使われました🌝�(https://3rdpartyjs.connpass.com/event/289558/)
  • 当日のLTはお酒をのみながらの時間だったため、かなり柔らかめの楽しさ満点スライドに仕上がっています✌

3 of 32

自己紹介

  • canalun (@i_am_canalun)
  • テックタッチでフロントエンドをやっています
    • 2022.1 エンジニアとしてテックタッチ入社
    • 2018.4 コンサルタントとしてマッキンゼー入社

4 of 32

趣味でやっていること

  • DOMDOMタイムス�(自分のzennで週刊連載👉)
  • TAPL.ts�(TAPLの輪読会👉)

オーム社 「型システム入門 プログラミング言語と型の理論」

5 of 32

要素が見えているかなんて興味ないよ……という人います!?

6 of 32

FE開発において、要素が見えているかを判定したいときが実はけっこうある!!

  • 「ある要素が見えているときだけ、うちのプロダクトを起動したい!」
  • 「うちのプロダクトの要素が表示された回数を知りたい!」

wikipediaトップページより

7 of 32

FE開発において、要素が見えているかを判定したいときが実はけっこうある!!

  • コンテンツの出し分け、表示タイミングの制御
  • コンテンツの表示・利用状況の把握

「見えている」

= 「ユーザーにとって見えている」

こういう定義でいきます🌝

wikipediaトップページより

8 of 32

要素が見えない!!!ってどんなとき?

思いを馳せてみてください

9 of 32

要素が「見えない」ときの代表パターン3つ

10 of 32

要素が「見えない」ときの代表パターン3つ

画面内にない

11 of 32

要素が「見えない」ときの代表パターン3つ

画面内にない

もともと見えない

12 of 32

要素が「見えない」ときの代表パターン3つ

画面内にない

もともと見えない

他の要素に覆われている

13 of 32

要素が「見えない」ときの代表パターン3つ

画面内にない

もともと見えない

他の要素に覆われている

ここを起点に

要素の”visibility”を考えます

順番に見ていきますよ〜!🌝🌝

14 of 32

要素の”visibility” その1

画面内に入ってるの?

wikipedia

トップページより

15 of 32

要素の”visibility” その2

「もともと」見えるモンなの??

visibilityの例

opacityやcontent-visibilityも関係する(後述)

MDN「visibility」より

16 of 32

要素の”visibility” その3

他の要素に覆われていないの?

wikipediaトップページより

17 of 32

要素の”visibility”には色々ある

  1. 画面内に入ってるの?
  2. もともと見えるモンなの?
  3. 他の要素に覆われていないの?

「見えている」を判定するときには、

どのレベルで判定するかを念頭において、

ロジックを書き分けないといけない!

18 of 32

ちょっと待ってよ!実際どう判定するのさ

  1. 画面内に入ってるの?

  1. もともと見えるモンなの?

  1. 他の要素に覆われていないの?

ここを

見てみよう!

今日はなし😭

19 of 32

「もともと見えるモンなの?」の判定は

考えることが多い……

サイズが0: width / height

boxがない: display / content-visibility

透明: opacity

invisible: visibility

祖先要素も見ないとあかん😭

20 of 32

「もともと見えるモンなの?」の判定は

考えることが多い……

サイズが0: width / height

boxがない: display / content-visibility

透明: opacity

invisible: visibility

こんなにやるの!?!?

21 of 32

「それ自体、見えているか?」の判定にはcheckVisibility()が使える!

「動機: 要素がそれ自体見えているかの判定は考えることが多いので、全部まとめたやつがほしい〜!」

Google; Chrome Platform Status「Feature: Element.checkVisibility method」より

22 of 32

checkVisibility()で確認してくれるコト

  • サイズが0: width / height
  • boxがない: display / content-visibility
  • 透明: opacity
  • invisible: visibility

祖先要素も見てくれる🌝

重要: 2023/9/29追記: checkVisibility()APIが要素のサイズについて確認してくれるという記述は誤りで、要素のサイズは確認されません!失礼しました🙇‍♂

23 of 32

checkVisibility()で確認してくれるコト

  • サイズが0: width / height
  • boxがない: display / content-visibility
  • 透明: opacity
  • invisible: visibility

祖先要素も見てくれる🌝

非対応ブラウザ向けには、

自分で実装しよう!

(w3cに実装の定義が載っているヨ)

(polyfillでもいいヨ)

24 of 32

でもさあ……

「そもそも見えているのか」の確認だけでは満足できない!

wikipedia�トップページより

25 of 32

でもさあ……

「そもそも見えているのか」の確認だけでは満足できない!

wikipedia�トップページより

「覆われていないか」を

見る必要がある

26 of 32

覆われているって何??

覆われているを定義してみる

27 of 32

覆われているって何??

覆われているを定義してみる

(定義の仕方で最適な判定の仕方が変わるので注意)

覆われていない

覆われている

28 of 32

「他の要素に覆われていないか?」の判定にelementsFromPoint()を使うアイデア

elementsFromPoint()を何点かに適用して判定!

だいたい5か所くらいでやってみよ〜!

覆われている

覆われていない

29 of 32

「他の要素に覆われていないか?」の判定にelementsFromPoint()を使うアイデア

elementsFromPoint()を何点かに適用して判定!

だいたい5か所くらいでやってみよ〜!

覆われている

覆われていない

これには落とし穴がある!

30 of 32

子要素に「覆われている」かも

ボタン要素が

子要素(画像やdiv)に「覆われている」

と判定されてしまう😭

Google 検索画面より

31 of 32

子要素に「覆われている」かも

ボタン要素が

子要素(画像やdiv)に「覆われている」

と判定されてしまう😭

Google 検索画面より

contains()も組み合わせればいい!

みんなも家でやってみてね🌝

32 of 32

まとめ

  • 要素が「見えている」と言っても色々ある
  • 自分が求めている「見えている」にマッチしたロジックで判定しよう👶
    • それ自体見えているか?: checkVisibility()
    • 覆われていないか?: elementsFromPoint()とcontains()
  • でもけっこう奥が深いから、その都度がんばって考えよう!