Help us understand the problem. What is going on with this article?

【jQuery】スクロールする要素内で指定要素が表示状態かを判定する

More than 5 years have passed since last update.

※自分でちょっとハマったのでメモします。

きっかけ

ページの四方をメニューなどで固定表示していて、中の要素を
overflow: scroll; しているとします。(UI的にどうなの?というのは置いといて)
この要素内の要素がスクロールによって表示されているかどうかを判定したい時

よくあるページ内のスクロール量によって処理する場合

//要素のスクロール位置
$(selector).offset().top;
//現在のスクロール位置
$('body,html').scrollTop();

これを比較してどうこうすれば行けますが
スクロールする要素内の要素のスクロール位置(もっといい表現ないかな。。)は
どうやって取るの?となりました。

シンプルなhtml構造なら、、、

以下の様にシンプルなhtml構造であれば $('.target').position().top で取れますが

<!-- スクロールする要素 -->
<div style="position: relative">
  <p>テキスト</p>
  <p>テキスト</p>
  <p class="target">ここを取りたい</p>
</div>

極端な話、以下の様な構造だと面倒です。

<!-- スクロールする要素 -->
<div style="position: relative">
  <div style="position: absolute">
    <p>テキスト</p>
    <p>テキスト</p>
  </div>
  <div style="position: absolute">
    <p>テキスト</p>
    <p>テキスト</p>
    <div style="position: absolute;">
      <p class='target'>ここを取りたい</p>
    </div>
  </div>
</div>

結局 offset() でいけましたっていう話

今件の場合、四方を固定されていて、スクロールするのはその中の要素です。
つまり、bodyはスクロールせず、中のdivなりがスクロールします。
この状態で以下の処理をしてみます。

var wh = $(window).height(),
    fh = $('footer').height();
//selector1はスクロールする要素
$(selector1).on('scroll', function() {
  //selector2は判定したい要素
  var t = $(selector2).offset().top;
  if (t < wh - fh) {
    console.log('表示エリアに入りました。');
  }
});

 offset() はbodyの左上を基点としますが(あえてbodyと書いています)、
bodyはスクロールしないため、結果判定したい要素が近づいてくる形になります。
これで window の高さと offset().top の値を比較すれば
表示されたかどうかがわかるわけです。
(減算している fh は下部に固定されている要素の高さ)

結論

四方が固定表示されていなくても、bodyがスクロールしない状態なら
上記方法でいけます。
offset() で取れる値は常に固定だよね」と思っていたのでハマりました。

※書いてみたものの、かなりわかりにくいですね。自分でも後から見直してわかるかどうか。。

bgn_nakazato
いつまでもビギナーなんです。
https://gieer.tech/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away