###実現したいこと
「Intersection Observer」を使い、要素が見えてからイベントを発火させたいです。
$(window).scroll(function(){});
の代わりに「Intersection Observer」を使ってスクロールイベントを実装したのですが、要素が見えていないのにイベントが発火してしまう現象にぶつかってしまいました。
発生している問題
以下ソースコードは
.Blue
が見えた段階でconsole.log('.Blueが表示されました');
を実行するという処理と、
.Red
が見えた段階でconsole.log('.Redが表示されました');
を実行するという処理を実装しています。
しかし読み込み直後の段階にまでconsole.log('.Redが表示されました');
が実行されてしまうのです。
###該当のソースコード
↓サンプル
https://jsfiddle.net/3syn1apv/
↓サンプルと同じコード
html
1<header><div>menu1</div><div>menu2</div></header> 2 3<section class="Gray"> 4 <div>contentsGray</div> 5</section> 6 7<section class="Red"> 8 <div>contentsRed</div> 9</section> 10 11<section class="Blue"> 12 <div>contentsBlue</div> 13</section>
css
1body { 2 background: #fff; 3 padding: 0; 4 margin: 0; 5} 6section { 7 height: calc(100vh - 50px); 8 padding: 50px 0 0 0; 9 background: gray; 10} 11section.Red.is_view{ 12 background: red; 13} 14section.Blue.is_view{ 15 background: blue; 16} 17header { 18 display: flex; 19 align-items: center; 20 justify-content: space-evenly; 21 position: fixed; 22 top: 0; right: 0; left: 0; 23 height: 50px; 24 background: black; 25 color: white; 26}
js
1// .Redが見えたらクラス付与 2const optionsRed = { 3 // オプション指定なし 4}; 5const observerRed = new IntersectionObserver((entries) => { 6 entries.forEach(entry => { 7 if( entry.isIntersecting ){ 8 console.log('.Redが表示されました'); 9 $('.Red').addClass('is_view'); 10 } 11 }); 12}, optionsRed); 13observerRed.observe( $(".Red")[0] ); 14 15// .BLueが見えたらクラス付与 16const observerBlue = new IntersectionObserver((entries) => { 17 entries.forEach(entry => { 18 if( entry.isIntersecting ){ 19 console.log('.Blueが表示されました'); 20 $('.Blue').addClass('is_view'); 21 } 22 }); 23}); 24observerBlue.observe( $(".Blue")[0] ); 25
試したこと
ぴったりだといけないのかと思い次のように「10%見えたとき(threshold: 0.1)」としてみたのですが、これでも読み込み直後に実行されてしまいました。
追記:Chromeで threshold: 0.1 で試したら平気でした。またFirefoxでもjsfiddleのsectionの高さが418.4pxの場合に平気でした。
js
1const optionsRed = { 2 // オプション指定なし 3}; 4 5// ↓ 指定 6 7const optionsRed = { 8 threshold: 0.1 // 10%見えたとき 9};
で解決したのは、HTMlから<header>
をなくし、.section{height:100vh:}
にするという次の方法です。
html
1<!-- <header><div>menu1</div><div>menu2</div></header> -->
css
1section { 2 /* height: calc(100vh - 50px); */ 3 /* padding: 50px 0 0 0; */ 4 background: gray; 5 height: 100vh; /* headerをなくしたので100vhへ変更 */ 6} 7
が…っ!!だめ、これではだめです。だって<header>
は必要です。
どうすれば先の問題を、<header>
周辺のデザインを変えることなくクリアできるでしょうか。