質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

283閲覧

JavaScript IntersectionObserverを使った監視がうまく動かない

mizuta_tamari

総合スコア3

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2024/07/06 14:11

実現したいこと

IntersectionObserverを使って画面に要素(.c-pads--06)が入ってきたら該当するすべての要素(.c-pads--worksがつくものすべて)にクラスを追加してアニメーションを発火させたいです。

発生している問題・分からないこと

以前質問した https://teratail.com/questions/sn37t9xks9maak こちらで使用したコード(回答いただいたものに修正済み)をそのまま使用したのですが、うまく動きませんでした。

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Document</title> 7 <link rel="stylesheet" href="style.css"> 8</head> 9<body> 10 <main> 11 <div class="height"></div> 12 <section> 13 <div class="p-background-pads p-background-pads--works"> 14 <img class="c-pads c-pads--works c-pads--01" src="img/pad.svg" width="74.8" height="58.07" alt=""> 15 <img class="c-pads c-pads--works c-pads--02" src="img/pad.svg" width="74.8" height="58.07" alt=""> 16 <img class="c-pads c-pads--works c-pads--03" src="img/pad.svg" width="74.8" height="58.07" alt=""> 17 <img class="c-pads c-pads--works c-pads--04" src="img/pad.svg" width="74.8" height="58.07" alt=""> 18 <img class="c-pads c-pads--works c-pads--05" src="img/pad.svg" width="74.8" height="58.07" alt=""> 19 <img class="c-pads c-pads--works c-pads--06" src="img/pad.svg" width="74.8" height="58.07" alt=""> 20 </div> 21 <div class="c-section-title c-section-title--works c-section-title--left"> 22 <div class="c-section-title-flex-container"> 23 <h2 class="c-section-title__ja">実績</h2> 24 <h3 class="c-section-title__en">Works</h3> 25 </div> 26 <span class="c-section-title__line-container"><div class="c-section-title__line"></div></span> 27 </div> 28 </section> 29</main> 30<script src="script.js"></script> 31</body> 32</html>

JavaScript

1const fadeImgs = document.getElementsByClassName("c-pads--works"); 2const fadeImg = document.querySelector(".c-pads--01"); 3const options = {threshold:1}; 4let fadeObserver = new IntersectionObserver((entries) => { 5 if(entries[0].isIntersecting) { 6 for(var i=0; i<fadeImgs.length; i++) { 7 var element = fadeImgs[i]; 8 element.classList.add("fade"); 9 console.log("success"+[i]); 10 } 11 } else { 12 return; 13 } 14}, options); 15fadeObserver.observe(fadeImg);

CSS

1@charset "UTF-8"; 2 3html, body, div, span, applet, object, iframe, 4h1, h2, h3, h4, h5, h6, p, blockquote, pre, 5a, abbr, acronym, address, big, cite, code, 6del, dfn, em, img, ins, kbd, q, s, samp, 7small, strike, strong, sub, sup, tt, var, 8b, u, i, center, 9dl, dt, dd, ol, ul, li, 10fieldset, form, label, legend, 11table, caption, tbody, tfoot, thead, tr, th, td, 12article, aside, canvas, details, embed, 13figure, figcaption, footer, header, hgroup, 14menu, nav, output, ruby, section, summary, 15time, mark, audio, video { 16 margin: 0; 17 padding: 0; 18 border: 0; 19 font-size: 100%; 20 font: inherit; 21 vertical-align: baseline; 22} 23 24/* HTML5 display-role reset for older browsers */ 25article, aside, details, figcaption, figure, 26footer, header, hgroup, menu, nav, section { 27 display: block; 28} 29 30body { 31 line-height: 1; 32} 33 34ol, ul { 35 list-style: none; 36} 37 38blockquote, q { 39 quotes: none; 40} 41 42blockquote:before, blockquote:after, 43q:before, q:after { 44 content: ""; 45 content: none; 46} 47 48table { 49 border-collapse: collapse; 50 border-spacing: 0; 51} 52/*----------------------------- 53テスト用追記 54-----------------------------*/ 55.height { 56 display: inline-block; 57 height: 2000px; 58} 59 60/*---------------------- 61base 62----------------------*/ 63*, *:before, *:after { 64 box-sizing: border-box; 65} 66 67body { 68 font-size: 16px; 69 line-height: 1.5; 70 font-family: "Noto Sans JP", Meiryo, sans-serif; 71 color: #333; 72 background-origin: border-box; 73 background-size: 30%; 74 overflow-x: hidden; 75} 76 77a { 78 color: inherit; 79 text-decoration: none; 80} 81a:hover { 82 text-decoration: none; 83} 84 85img { 86 max-width: 100%; 87 vertical-align: middle; 88} 89 90input { 91 margin: 0; 92 padding: 0; 93} 94 95textarea { 96 padding: 0; 97 font: inherit; 98 color: inherit; 99} 100 101input::-moz-placeholder { 102 font-family: "Noto Sans JP", Meiryo, sans-serif; 103 font-size: 1rem; 104} 105 106input::placeholder { 107 font-family: "Noto Sans JP", Meiryo, sans-serif; 108 font-size: 1rem; 109} 110 111input::-moz-placeholder, textarea::-moz-placeholder { 112 color: #B0B0B0; 113} 114 115input::placeholder, textarea::placeholder { 116 color: #B0B0B0; 117} 118 119button { 120 font: inherit; 121 padding: 0; 122 background-color: transparent; 123 border: none; 124 color: inherit; 125 cursor: pointer; 126} 127 128.p-grid-wrapper { 129 width: 85.4166666vw; 130 display: grid; 131 margin: 0 auto; 132} 133 134/*------------------------------- 135site-title 136-------------------------------*/ 137.c-site-title__title { 138 padding: 249px 0 156px 0; 139 margin: 0 auto; 140 text-align: center; 141 font-size: 2rem; 142 font-weight: 100; 143} 144.c-site-title__arrow-container { 145 margin: 0 auto; 146 text-align: center; 147} 148.c-site-title__arrow { 149 position: relative; 150 display: inline-block; 151 width: 1px; 152 height: 171px; 153 margin: 0 17.7px 300px 17.7px; 154 border-radius: 9999px; 155 background-color: #333; 156 -webkit-animation: line-move 5s ease-in-out infinite; 157 animation: line-move 5s ease-in-out infinite; 158} 159.c-site-title__arrow::before, .c-site-title__arrow::after { 160 content: ""; 161 position: absolute; 162 bottom: 0; 163 left: calc(50% - 0.5px); 164 width: 1px; 165 height: 26px; 166 border-radius: 9999px; 167 background-color: #333; 168 transform-origin: 50% calc(100% - 0.5px); 169} 170.c-site-title__arrow::before { 171 transform: rotate(45deg); 172} 173.c-site-title__arrow::after { 174 transform: rotate(-45deg); 175} 176.c-site-title__arrow-text { 177 transform: rotate(90deg); 178 padding-left: 30px; 179} 180.c-site-title__arrow-container { 181 height: 171px; 182} 183 184@-webkit-keyframes line-move { 185 0% { 186 height: 0; 187 top: 0; 188 } 189 33% { 190 height: 171px; 191 top: 0; 192 } 193 66% { 194 height: 0px; 195 top: 171px; 196 } 197 100% { 198 height: 0; 199 top: 0; 200 } 201} 202 203@keyframes line-move { 204 0% { 205 height: 0; 206 top: 0; 207 } 208 33% { 209 height: 171px; 210 top: 0; 211 } 212 66% { 213 height: 0px; 214 top: 171px; 215 } 216 100% { 217 height: 0; 218 top: 0; 219 } 220} 221 222/*------------------------ 223section-title 224------------------------*/ 225 226.c-section-title { 227 color: #FF472E; 228 line-height: 1; 229} 230.c-section-title-flex-container { 231 display: flex; 232 align-items: flex-end; 233 flex-wrap: nowrap; 234} 235.c-section-title__ja { 236 flex: 1; 237 font-weight: 100; 238 white-space: nowrap; 239 font-size: 13vw; 240} 241.c-section-title__en { 242 flex: 1; 243 margin-right: 7.291666vw; 244 text-align: right; 245} 246.c-section-title__line-container { 247 display: block; 248 height: 64px; 249 width: 92.708334vw; 250} 251.c-section-title__line { 252 content: ""; 253 display: inline-block; 254 border-top: 1px solid #333; 255 height: 64px; 256 width: 0; 257} 258.c-section-title__line.on { 259 -webkit-animation: liner 1s linear forwards; 260 animation: liner 1s linear forwards; 261} 262@-webkit-keyframes liner { 263 0% { 264 width: 0; 265 } 266 100% { 267 width: 100%; 268 } 269} 270@keyframes liner { 271 0% { 272 width: 0; 273 } 274 100% { 275 width: 100%; 276 } 277} 278 279 280section { 281 position: relative; 282} 283 284.c-pads { 285 position: absolute; 286} 287 288/*--------------------------- 289background-decoration 290--------------------------*/ 291 292.p-background-pads { 293 position: absolute; 294} 295 296.p-background-pads--works { 297 aspect-ratio: 600/620; 298 width: 40vw; 299 top: -25.2vw; 300} 301 302.p-background-pads .c-pads--01 { 303 top: 0; 304 left: 1.44%; 305 transform: rotate(144.53deg); 306} 307.p-background-pads .c-pads--02 { 308 top: 28.09%; 309 left: 0.64%; 310 transform: rotate(169.49deg); 311} 312.p-background-pads .c-pads--03 { 313 top: 21.19%; 314 left: 34.66%; 315 transform: rotate(156.85deg); 316} 317.p-background-pads .c-pads--04 { 318 top: 47.86%; 319 left: 41.72%; 320 transform: rotate(144.74deg); 321} 322.p-background-pads .c-pads--05 { 323 top: 59.16%; 324 left: 77.66%; 325 transform: rotate(168.17deg); 326} 327.p-background-pads .c-pads--06 { 328 top: 85.06%; 329 left: 89.06%; 330 transform: rotate(168.17deg); 331}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

エラー等は出ず、if(entries[0].isIntersecting)がfalseのままで画面内に要素が入ってきたことを認識できていないようでした。
divの.heightは高さを出してObserverの監視状態を分かりやすくするために一時的に入れています。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2024/07/07 00:30

> if(entries[0].isIntersecting)がfalseのままで というのは、上記JavaScriptの4行目と5行目の間に、 console.log(entries[0].isIntersecting); を入れると、false と表示されたという意味でしょうか? ドキュメントをみるとそれは要素がビューから出て行ったという通知のようですね。
mizuta_tamari

2024/07/07 00:37

if(entries[0].isIntersecting)のelse returnの前にfalseと表示されるconsole.logを置いたところ、そのconsole.logだけが表示されました。 entries[0].isIntersectingは交差しているかどうかの判別なのでfalseだけ出力されるというのはそもそも要素と交差していないという認識なのですが、どうでしょうか?
otn

2024/07/07 01:39

交差のthreshold値の範囲を上から下、あるいは下から上に越えた時に、コールバックが呼ばれるので、 ・範囲から出た(isIntersectingがfalse) ・範囲に入った(isIntersectingがtrue) のどっちでも呼ばれるようです。 threshold:1 が危ういかなと思っていたのですが、やっぱりそこでしたか。デフォルト値を使わない訳なので、十分な意図があっての変更だったのかとは思いますが。
guest

回答1

0

ベストアンサー

「該当のソースコード」の状態で「success0」などのログが出力されないということですよね。

「実現したいこと」には「画面に要素(.c-pads--06)が入ってきたら」と記載されていますが、
「該当のソースコード」にはconst fadeImg = document.querySelector(".c-pads--01");のように記述されているようです。

.c-pads--01.c-pads--06のように変更すると、
「success0」などのログが出力されることが確認できました。
(Safariで確認)

.c-pads--01で「success0」などのログが出力されない原因は、
画像が回転していて左側がほんの少し画面の外にあるからのように思いました。
オプションのthresholdを0.5とか小さい値にすると.c-pads--01でも「success0」などのログが確認できました。
const options = {threshold:0.5};

回転していても画像全体が画面の中に収まるように位置を調整するか、
thresholdでどのくらいの割合見えたら反応するように調整するか、
このあたりを試してみると良いかなと思いました。

threshold
単一の数値または数値の配列で、ターゲットがどのくらいの割合で見えている場合にオブザーバーのコールバックを実行するかを示します。見える範囲が 50% を超えたときのみ検出する場合は値 0.5 を使用します。 25% を超える度にコールバックを実行する場合は、 [0, 0.25, 0.5, 0.75, 1] という配列を指定します。既定値は 0 です(つまり、 1 ピクセルでも表示されるとコールバックが実行されます)。 1.0 の値は全てのピクセルが見えるようになるまで、閾値を超えたとはみなされないことを意味します。

交差オブザーバー API - Web API | MDN

投稿2024/07/07 00:44

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mizuta_tamari

2024/07/07 00:51

監視対象を仮として01にしていたことを忘れていました。回転していて要素が100%見えない状態になっている+threshold:1を指定していると100%見えているように見えたとしても閾値を超えたとはみなされないということですね。監視対象を06に変更したらうまくいきました。(ついでに01を監視対象にしてthreshold:0.5を指定したところこちらもうまくいきました)ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問