【问题标题】:Why does InteractionObserver not work on my website?为什么 IntersectionObserver 不能在我的网站上运行?
【发布时间】:2021-06-01 08:40:44
【问题描述】:

编辑: 这篇文章已经过编辑,以标记从以前的 jQuery 装置中对纯 JS InteractionObserver 实例的更新,该装置使网站变得非常缓慢。

新问题是我设法让 Rickard 的想法在 Codepen 上进行了一些样式调整(进入时将 .hidden 更改为反向 .visible 类),但对于我的生活,它对我的​​生活不起作用网站。

具体来说,我认为交叉点没有切换,我同时使用了 console.log 和提示符进行检查,即使逐字复制代码,它们也根本没有启动。

旧代码,用于上下文:

  // $(document).ready shorthand
  $("section, img, p, h1, h2, h3, h4, span").fadeIn("slow"); });

$(document).ready(function() {
  /* Every time the window is scrolled ... */
  $(window).scroll(function() {
    /* Check the location of each desired element */
    $("section, img, p, h1, h2, h3, h4, span").each(function(i) {
      var bottom_of_object = $(this).position().top + $(this).outerHeight();
      var bottom_of_window = $(window).scrollTop() + $(window).height();
      /* If the object is completely visible in the window, fade it in */
      if (bottom_of_window > bottom_of_object - 200) {
        $(this).animate({ opacity: "1" }, 1000),
        $(this).find('.lefttitle').animate({left:"0px"}, 1500);
        $(this).find('.righttitle').animate({right:"0px"}, 1500);
      }}); }); });

旧 CSS 标题

h2.lefttitle {float:left; text-align:left; left:10px; top:6px;}
h2.righttitle {float:right; text-align:right; right:10px; top:-6px;}

旧 CSS 动画

h3, section.projdescription * {animation:fadeInUp 2s both ease;}
*.visible {animation:fadeInUp 4s both ease;}
@keyframes fadeInUp {
  0% {opacity: 0;transform: translate3d(0,10px,0);}
  100% {opacity: 1;} }

【问题讨论】:

    标签: javascript jquery class animation


    【解决方案1】:

    IntersectionObserver 一开始可能很难理解。您在要触发观察者 (see 1) 的每个 (section) 元素上放置一个观察者。将它们视为添加到数组 (entries)。然后观察者触发并将数组作为参数提供给您,您需要遍历它们中的每一个以查看它们是否相交 (see 2)。

    很抱歉没有用 JQuery 写这个,但我对它很生疏,因为 JQuery 在今天并不是真正需要的。

    // 2
    let observer = new IntersectionObserver((entries) => {
      let section;
    
      // The same as writing ...
      // entries.forEach(function(entry) {
    
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          section = entry.target;
          section.classList.remove('hidden');
        }
      })
    });
    
      // 1
    document.querySelectorAll('section').forEach((section) => {
      observer.observe(section);
    });
    section {
      color: white;
      font-size: 20px;
      padding: 1rem;
      min-height: 100vh;
      transition: opacity 5s;
    }
    
    section.hidden {
      opacity: 0;
    }
    
    section > .text {
      transition: transform 4s;
    }
    
    section.hidden > .text {
      transform: translateX(-2rem);
    }
    
    .blue {
      background-color: blue;
    }
    
    .red {
      background-color: red;
    }
    
    .black {
      background-color: black;
    }
    <section class="hidden blue">
      <div class="text">Something</div>
    </section>
    
    <section class="hidden red">
      <div class="text">Something, something</div>
    </section>
    
    <section class="hidden black">
      <div class="text">Last one, now!</div>
    </section>

    【讨论】:

    • 设法在Codepen 上进行了一些样式调整(进入时将 .hidden 更改为反向 .visible 类),但对于我的生活,它在我的网站上不起作用。具体来说,这是我认为没有切换的交叉点,我同时使用了 console.log 和提示符来检查。
    【解决方案2】:

    您在滚动的每个像素中都循环了很多元素,然后为 leftright 属性设置动画,这会强制重新计算所有对象并重新绘制。我会说浏览器会跳过动画,因为发生的事情太多了。

    1. 不要在滚动时设置动画。使用IntersectionObserver
    2. 请勿使用leftrighttopbottom 制作动画。使用transform: translate 制作动画(就像您的动画一样),它不会强制重新计算其他元素的位置。热修复是使用transform3d 来激活硬件中的 3d 渲染。
    3. 您不需要使用关键帧来制作动画。只需使用transition,并为元素添加一个相关的类,当intersectionObserver 触发时,它会改变它的位置或不透明度。

    【讨论】:

      【解决方案3】:

      终于成功了!

      下面是让魔法发生的 JS 代码:

      /* Margins for the Intersection */
      const observerOptions = {
           root: null,
           threshold: 0,
           rootMargin: '0px 0px -100px 0px'
      };
      
      /* Add .visible Class to Intersection */
      const observer = new IntersectionObserver(entries => {
           entries.forEach(entry => {
               if (entry.isIntersecting) {
                 entry.target.classList.add('visible');
                 observer.unobserve(entry.target);
               }
           });
      }, observerOptions);
      
      /* Listener for every element on the page */
      window.addEventListener('DOMContentLoaded', (event) => {
        const sections = Array.from(document.querySelectorAll("*"));
        for (let section of sections) {
          observer.observe(section);
        }
      });
      
      

      现在这里有一些用于动画的 CSS:

      /* Set the Initial State */
      section, img, h1, etc {
        transition: padding-top 1s ease, opacity 1.5s ease;
        opacity: 0;
        padding-top: 20px;}
      /* Act on Adding Visible State */
      section.visible, img.visible, h1.visible, etc {
        opacity: 1;
        padding-top: 0px;}
      /* Micromanage the Transitions */
      img.visible {transition-duration: 0.5s}
      h1.visible {transition-duration: 0.5s;}
      
      

      现在继续改进它。我可能会将 JS querySelector 上的“*”更改为更简洁的选择(部分、img 等),但现在,它可以创造奇迹!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-12
        • 2017-09-27
        • 2021-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-06
        • 2012-09-13
        相关资源
        最近更新 更多