animate-titleクラスの要素(3つあります)がそれぞれ画面内に入ったときに、アニメーションを開始するよう実装しようと、以下のコードを書いたのですが、なぜか一番初めのanimate-titleクラスの要素が分割されて表示されました。
よく見てみると<span>の文字まで分割されているので、何度も同じ要素が取得されて、それに対してさらにHTML要素が分割されています。
どうしてこうなるのかがずっと分かりません。
是非教えていただけると嬉しいです。
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous"> 9 <link href="https://fonts.googleapis.com/css2?family=Teko:wght@500&display=swap" rel="stylesheet"> 10 <link rel="stylesheet" href="style.css"> 11 <title>Document</title> 12</head> 13 14<body> 15 <section> 16 <div class="animate-title">Start where you are.</div> 17 </section> 18 <section> 19 <div class="animate-title">Use what you have.</div> 20 </section> 21 <section> 22 <div class="animate-title">Do what you can.</div> 23 </section> 24 <script src="text-animation.js"></script> 25 <script src="main.js"></script> 26</body> 27 28</html>
JavaScript
1class TextAnimation { 2 constructor(el) { 3 this.DOM = {}; 4 this.DOM.el = document.querySelector(el); //animate-titleのDOMが格納される 5 this.chars = this.DOM.el.innerHTML.trim().split(""); 6 this.DOM.el.innerHTML = this._splitText(); 7 } 8 _splitText() { 9 return this.chars.reduce((acc, curr) => { 10 curr = curr.replace(/\s+/, ' '); 11 return `${acc}<span class="char">${curr}</span>`; 12 }, ""); 13 } 14 animate() { 15 this.DOM.el.classList.add('inview'); 16 } 17} 18 19document.addEventListener("DOMContentLoaded", function () { 20 21 const cb = function (entries, observer) { 22 entries.forEach((entry) => { 23 if (entry.isIntersecting) { //elが画面内に入ってきたとき 24 const ta = new TextAnimation(".animate-title"); 25 ta.animate(); 26 observer.unobserve(entry.target); 27 } else { 28 29 } 30 }); 31 // alert('intersecting'); 32 }; 33 const options = { 34 root: null, 35 rootMargin: "-300px 0px", 36 threshold: [0, 0.5, 1], 37 }; 38 39 const io = new IntersectionObserver(cb, options); 40 const els = document.querySelectorAll(".animte-title"); 41 els.forEach(el => io.observe(el)); 42 //elsが複数あるのでforEachですべての要素についてintersectionobserverを設置 43});
2020.09.25追記
アニメーションの見本はこのような感じです。
https://gyazo.com/379b7940d55ff1e239767706a690744b
(gifを貼り付けられなかったので、いったんこちらにリンクを貼ります。解決し次第編集してプレビューが見れるように善処します)
回答1件
あなたの回答
tips
プレビュー