1 of 34

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

はじまるよ〜!

2 of 34

自己紹介

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

3 of 34

趣味でやっていること

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

4 of 34

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

5 of 34

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

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

6 of 34

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

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

「見えている」

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

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

7 of 34

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

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

8 of 34

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

9 of 34

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

画面内にない

10 of 34

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

画面内にない

もともと見えない

11 of 34

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

画面内にない

もともと見えない

他の要素に覆われている

12 of 34

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

画面内にない

もともと見えない

他の要素に覆われている

ここを起点に

要素の”visibility”を考えます

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

13 of 34

要素の”visibility” その1

画面内に入ってるの?

14 of 34

要素の”visibility” その2

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

visibilityの例

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

15 of 34

要素の”visibility” その3

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

16 of 34

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

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

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

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

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

17 of 34

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

  • 画面内に入ってるの?

  • もともと見えるモンなの?

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

ここを

見てみよう!

今日はなし😭

18 of 34

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

考えることが多い……

boxがない: display / content-visibility

透明: opacity

invisible: visibility

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

19 of 34

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

考えることが多い……

boxがない: display / content-visibility

透明: opacity

invisible: visibility

こんなにやるの!?!?

20 of 34

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

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

21 of 34

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

  • boxがない: display / content-visibility
  • 透明: opacity
  • invisible: visibility

祖先要素も見てくれる🌝

22 of 34

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

  • boxがない: display / content-visibility
  • 透明: opacity
  • invisible: visibility

祖先要素も見てくれる🌝

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

自分で実装しよう!

(テックタッチも自前でやってるヨ)

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

(polyfillでもいいヨ)

23 of 34

でもさあ……

「そもそも見えているのか」を確認するだけじゃダメ

24 of 34

でもさあ……

「そもそも見えているのか」を確認するだけじゃダメ

「覆われていないか」を

見る必要がある

25 of 34

覆われているって何??

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

26 of 34

覆われているって何??

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

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

覆われていない

覆われている

27 of 34

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

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

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

覆われている

覆われていない

28 of 34

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

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

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

覆われている

覆われていない

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

29 of 34

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

ボタン要素が

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

と判定されてしまう😭

30 of 34

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

ボタン要素が

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

と判定されてしまう😭

contains()も組み合わせる!

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

31 of 34

まとめ

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

32 of 34

app.

33 of 34

「他の要素に覆われていないか?」の判定にはelementsFromPoint()とcontains()を使える!

shadow DOMに注意!

34 of 34

要素が「見えている」その3

内容は変わっていないか?

li要素のテキストが変わっているだけ。要素自体は使い回し。

しかし、見えなくなったように知覚される