Запускать анимацию каждый раз, когда она находится в области просмотра

У меня есть этот код

//new IntersectionObserver();
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    //console.info(entry)
    if (entry.isIntersecting) {
      entry.target.firstChild.classList.add('tag');
    } else {
      entry.target.firstChild.classList.remove('tag');
    }
  })
})

const hiddenElements = document.querySelectorAll("h1");
hiddenElements.forEach((el) => observer.observe(el));
html {
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
  overscroll-behavior-y: contain;
}

section {
  scroll-snap-align: start;
  scroll-snap-stop: always;
  /*scroll-margin: 5vh;*/
  min-height: 100vh;
  
  display: flex;
  align-items: center;
  justify-content: center;
}

.tag {
  color: #0000;
  --g: linear-gradient(beige 0 0) no-repeat;
  background: var(--g), var(--g);
  background-size: 0% 100%;
  -webkit-background-clip: padding-box, text;
  background-clip: padding-box, text;
  animation: t 1.2s .5s both, b 1.2s 1.3s both;
}

p1 {
  line-height: 25px;
  color: beige;
  overflow-wrap: wrap;
  word-wrap: break-word;
  hyphens: auto;
  max-width: 60vw;
  font-size: 1,5vw;
  margin-top: 1vh;
  margin-right: 1vw;
  margin-left: 1vw;
  text-align: justify;
}

h1 { color: beige; 
  font-family: 'Open Sans Condensed', sans-serif; 
  font-size: 4vh;
  font-weight: 700;
  line-height: 50px; margin: 0 0 0;
  padding: 20px 30px;
  text-align: center;
  text-transform: uppercase; 
}

@keyframes t {
  to {
    background-size: 150% 100%
  }
}

@keyframes b {
  to {
    background-position: -200% 0, 0 0
  }
}

.hidden {
  opacity: 0;
}


@keyframes t{
  to {background-size: 150% 100%}

}
@keyframes b {
  to {background-position:-200% 0,0 0}
}

h1 { color: beige; 
  font-family: 'Open Sans Condensed', sans-serif; 
  font-size: 4vh;
  font-weight: 700;
  line-height: 50px; margin: 0 0 0;
  padding: 20px 30px;
  text-align: center;
  text-transform: uppercase; 
}
<!DOCTYPE html5>
<html>   
    <head>
        <html lang = "cz"></html>
        <meta charset = "UTF-8">
        <link rel = "stylesheet" href = "styly.css">
        <script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script type = "text/javascript" src = "script.js"></script>
        <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
    </head>

    <body>
      
      <!-- 1. okn - Úvod -->
      <section style = "display: flex;">
        <img class = "logo" src = "Original.svg" id = "logo"> <!-- logo  -->
        <p3> <!--  -->
          text tmsdlnvlsůsnskf
        </p3>
        
        

        <p2> 
          „text text text text text text text text text text text“
        </p2>
        <div class = "sipky_d">
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
         </div>
      </section>

      <!-- 2. window -->
      <section>
        <div class = "sipky_n">
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
        </div>

        <img class = "profile_photo" src = "foto.jpg" id = "pfp">
        <p1 style = "float: right;">
          text text text text text text text text text text text
        </p1>
        <div class = "links">
          <button class = "button" onclick = "window.open('tel:')">Call</button>
          <button class = "button" onclick = "window.location.href='mailto:mail'">e-mail</button>
          <button class = "button" onclick = "window.location.href='www.google.com'">Facebook</button>
       </div>

        <p4>text text text text text text text text text text text</p4>

       <div class = "sipky_d">
        <div class = "sipka_d"></div>
        <div class = "sipka_d"></div>
        <div class = "sipka_d"></div>
       </div>
       
      </section>

      <!-- 3. window -->
      <section>
       <div class = "sipky_n">
        <div class = "sipka_n"></div>
        <div class = "sipka_n"></div>
        <div class = "sipka_n"></div>
       </div>

        
        <p1>  
          <h1><span class = "tag">Text that I want to animate</span></h1>
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text 
        </p1>

          <div class = "sipky_d">
            <div class = "sipka_d"></div>
            <div class = "sipka_d"></div>
            <div class = "sipka_d"></div>
          </div>

      </section>
  
      <!-- 4. window -->
      <section>
      <div class = "sipky_n">
        <div class = "sipka_n"></div>
        <div class = "sipka_n"></div>
        <div class = "sipka_n"></div>
      </div>


       <p1> 
         <br><br>text text text text text text text text text text text
         <br><br>text text text text text text text text text text text
         <br><br>text text text text text text text text text text text
         </p1>

         <div class = "sipky_d">
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
         </div>
      </section>

      <!-- 5. window -->
      <section>
        <div class = "sipky_n">
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
        </div>

        <p1>
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>Správní právo
          <br><br>text text text text text text text text text text text
        </p1>

        <div class = "sipky_d">
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
         </div>
      </section>

      <!-- 6. window -->
      <section>
            <div class = "sipky_n">
              <div class = "sipka_n"></div>
              <div class = "sipka_n"></div>
              <div class = "sipka_n"></div>
            </div>
            <p1>
              <br><br>text text text text text text text text text text text
              <br><br>text text text text text text text text text text text
              <br><br>text text text text text text text text text text text
              <br><br>text text text text text text text text text text text
              <ul>
                <li>text text text text text text text text text text text</li>
                <li>text text text text text text text text text text text</li>
                <li>text text text text text text text text text text text</li>
              </ul>
            </p1>
            <div class = "sipky_d">
              <div class = "sipka_d"></div>
              <div class = "sipka_d"></div>
              <div class = "sipka_d"></div>
             </div>
      </section>

      <!-- 7. window -->
      <section>
        <div class = "sipky_n">
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
        </div>
        <p1>
          <br><br>Jtext text text text text text text text text text text
        
        <br><br>
        <div class = "map-responsive">
            <iframe src = "" allowfullscreen = "" loading = "lazy" referrerpolicy = "no-referrer-when-downgrade"></iframe>
        </div>
        <br><br>
        
          text text text text text text text text text text text
          <br><br>
          text text text text text text text text text text text
        </p1>
        <div class = "sipky_d">
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
          <div class = "sipka_d"></div>
         </div>
      </section>
  
      <!-- 8. window -->
      <section style = "scroll-padding: -50vh;">
        <div class = "sipky_n">
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
          <div class = "sipka_n"></div>
        </div>
        <p1>
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text

          text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
          <br><br>text text text text text text text text text text text
        </p1>
        <div style = "margin-left: 18vw;"></div> 
      </section>

      <div style = "scroll-margin-block-end: -20vh;"></div>
    </body>

</html>

Я хочу запускать анимацию каждый раз, когда она появляется в окне просмотра. В основном теле HTML у меня есть несколько элементов <section> и функция привязки прокрутки. Анимация воспроизводится правильно и работает, но воспроизводится только один раз. Я бы хотел, чтобы он воспроизводился каждый раз, когда он появляется в окне просмотра.

Я попробовал несколько уроков по JS, которые воспроизводят анимацию, когда она появляется в окне просмотра, но ни один из них не сработал.

Я добавил наблюдателя в JavaScript и дал ссылку на JavaScript в HTML. Анимация воспроизводится один раз. Когда я прокручиваю вверх или вниз, анимация не воспроизводится, а есть только текст. Похоже, анимация воспроизводится только один раз и больше никогда, пока я не обновлю страницу.

Edit2: я добавил образец HTML. Страница состоит из нескольких разделов, которые отображаются при прокрутке пользователем вверх или вниз. Текст должен анимироваться каждый раз, когда раздел появляется в поле зрения.

Edit3: я использовал предоставленный код и поместил его как в свои файлы, так и во фрагмент. Во фрагменте он работает отлично, но когда я запускаю html-файл в браузере, он все равно анимируется только один раз. Другого js нет. Может ли какой-то другой код CSS заставить его не работать?

Edit4: весь HTML-код находится здесь, и он работает так, как задумано. Даже когда я вставляю весь код CSS в фрагмент, он работает. Я попытался сделать это заново, скопировал HTML в новый файл, добавил CSS только для анимированного текста и JavaScript. И снова он сыграл только один раз. Я попытался удалить код CSS в частях CSS «html» и «раздел», но ничего из этого не помогло. Я подумываю об отказе от этой функции.

Edit5: я поместил js-скрипт непосредственно в html следующим образом:

 <p1>  
          <h1><span class = "tag">Text that I want to animate</span></h1>
          <script>
            const observer = new IntersectionObserver((entries) => {
               entries.forEach((entry) => {
               //console.info(entry)
               if (entry.isIntersecting) {
               entry.target.firstChild.classList.add('tag');
              } else {
               entry.target.firstChild.classList.remove('tag');
               }
              })
             })

         const hiddenElements = document.querySelectorAll("h1");
         hiddenElements.forEach((el) => observer.observe(el));
          </script>
          <br><br>text text text
          <br><br>text text text text
          <br><br>text text text text 
</p1>

И это работает именно так, как задумано. Так что спасибо всем, кто внес свой вклад. Большое спасибо A Haworth за исправления JavaScript!

что ты имеешь в виду под every time it comes into the viewport ? область просмотра - это просто концепция окружающей среды...

Mister Jojo 24.02.2024 13:27

Если вы хотите запускать его каждый раз, когда h1 появляется в окне просмотра, загляните в Intersection Observer.

A Haworth 24.02.2024 14:01

Я имею в виду, когда анимированный текст виден пользователю. Когда пользователь будет прокручивать вверх, он не будет виден. Когда пользователь прокручивает вниз, текст анимируется.

Jacob 24.02.2024 14:01

В этом вам поможет IntersectionObserver.

A Haworth 24.02.2024 14:04

Вы консоль проверяли? Так как в вашем коде есть несколько ошибок. 1. Первый new IntersectionObserver(); можно опустить. 2. foreach должно быть forEach

Reyno 24.02.2024 14:17

«Не работает» не очень помогает. Что не работает? Какую отладку вы делали? Например, вводится ли вообще код наблюдателя? Возможно, создайте работоспособный фрагмент, чтобы нам было легче помочь. См. stackoverflow.com/help/minimal-reproducible-example

A Haworth 24.02.2024 14:17

Что делает ваш фрагмент прокручиваемым? Пожалуйста, убедитесь, что на нем отображается проблема, так как я не могу его прокрутить.

A Haworth 24.02.2024 20:05

Теперь он прокручивается, а также имеет код из моего ответа, у меня все работает нормально. Есть ли еще проблема?

A Haworth 24.02.2024 20:11

Я совершенно не понимаю, почему это не работает. Я разместил во фрагменте весь соответствующий код (я исключил те, которые определяют стиль других частей сети, таких как карта или анимация стрелок), и он работает безупречно. Я постараюсь сделать сайт снова с нуля, если там возникнут проблемы или что-то в этом роде. Спасибо за код, это очень помогло.

Jacob 24.02.2024 20:11

Значит, этот фрагмент вам подходит? Если да, то да, вам нужно предоставить код, который не работает!

A Haworth 24.02.2024 20:15

Фрагмент работает отлично, но при вставке в остальной код он не работает. Я мог бы попытаться перенести весь код во фрагмент.

Jacob 24.02.2024 21:35

Это может быть тот случай, когда нам нужно увидеть реальный сайт, на котором он не работает, поскольку все по этому вопросу в представленном виде работает нормально. Есть ли у вас обычные заголовки, например, тип документа в вашей реальной системе?

A Haworth 25.02.2024 15:52

Да, именно так и есть у меня в "живых" файлах и на сайте. У меня возникла идея попробовать поместить css/js непосредственно в тег html и посмотреть, как это можно исправить. Я попробую и отчитаюсь.

Jacob 25.02.2024 16:24

Хорошо, я как-то заставил это работать? См. Edit5 в моем посте. Спасибо всем за вашу помощь! Желаю всем чудесного утра, дня или вечера.

Jacob 25.02.2024 16:31

Обратите внимание, что html5 в doctype shd. быть html - и я полагаю, что закрывающий тег html, который был раньше в строке 2, был неверным.

A Haworth 25.02.2024 16:52
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
2
15
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Помимо ошибок, указанных @Reyno, которые следует обнаружить, посмотрев на консоль средства проверки инструментов разработчика вашего браузера, класс тега добавляется/удаляется неправильно двумя способами: точка перед тегом и его добавлен в h1, хотя вы хотите, чтобы он находился в дочернем диапазоне.

Этот фрагмент выполняет несколько простых исправлений этих ошибок:

//new IntersectionObserver();
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    //console.info(entry)
    if (entry.isIntersecting) {
      entry.target.firstChild.classList.add('tag');
    } else {
      entry.target.firstChild.classList.remove('tag');
    }
  })
})

const hiddenElements = document.querySelectorAll("h1");
hiddenElements.forEach((el) => observer.observe(el));
.tag {
  color: #0000;
  --g: linear-gradient(beige 0 0) no-repeat;
  background: var(--g), var(--g);
  background-size: 0% 100%;
  -webkit-background-clip: padding-box, text;
  background-clip: padding-box, text;
  animation: t 1.2s .5s both, b 1.2s 1.3s both;
}

@keyframes t {
  to {
    background-size: 150% 100%
  }
}

@keyframes b {
  to {
    background-position: -200% 0, 0 0
  }
}

.hidden {
  opacity: 0;
}

div {
  height: 200vh;
}
<h1><span>My text to animate</span></h1>
<div>big div to create scrolling</div>

Спасибо! Это именно то, чего я хочу достичь. К сожалению, текст анимируется только один раз. Я добавил образец HTML на случай, если возникнет проблема. Я, честно говоря, не знаю, в чем проблема.

Jacob 24.02.2024 19:00

Я не понимаю HTML, который вы только что добавили к вопросу. Что такое элемент p1? Пожалуйста, превратите код в работоспособный фрагмент и убедитесь, что он показывает проблему. (в нынешнем виде я не вижу, чтобы ваш HTML мог вызвать какую-либо потенциальную прокрутку).

A Haworth 24.02.2024 19:17

Я добавил фрагмент. Я использовал ваш код (который добавил в свои файлы), и он работает безупречно. Почему это не работает в файле, мне непонятно. Я думаю, с ним взаимодействует какая-то другая часть кода? Рядом с этим нет js. Может ли это быть проблема css?

Jacob 24.02.2024 19:50

Другие вопросы по теме