繁体   English   中英

淡入淡出恰好一次

[英]Fade-in fade-out exactly once

我想让带有 class 的元素在第一次出现在屏幕上时fade淡出,然后在离开屏幕时淡出。

我希望这个 animation 只发生一次。

以下是我尝试过的。

.fade {
   /* transition: opacity 0.9s ease-in;*/
    opacity: 0;   
  }

.fade.visible {
  transition: opacity 0.9s ease-in;
  opacity: 1;
}
window.addEventListener('scroll', fade)
function fade()
{
  let animation=document.querySelectorAll('.fade');
   for (let i=0; i<animation.length; i++)
    {
     let windowheight=window.innerHeight;
     let top=animation[i].getBoundingClientRect().top;
     if (top < windowheight)
     {
       animation[i].classList.add('visible');
     }
     else
     {
       animation[i].classList.remove('visible');
     }    
    }
}

使用IntersectionObserver API而不是昂贵的滚动侦听器!

这是一个示例,当元素在视口中时触发 classList 更改 - 基于此答案,唯一的区别是此示例使用classList.add而不是classList.toggle

 const inViewport = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add("is-inviewport"); } }); }; const Obs = new IntersectionObserver(inViewport); const obsOptions = {}; //See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options // Attach observer to every [data-inviewport] element: const ELs_inViewport = document.querySelectorAll('[data-inviewport]'); ELs_inViewport.forEach(EL => { Obs.observe(EL, obsOptions); });
 [data-inviewport] { /* FOR THIS DEMO ONLY */ width:100px; height:100px; background:#0bf; margin: 150vh 0; } /* inViewport */ [data-inviewport="fade"] { transition: opacity 2s; opacity: 0; } [data-inviewport="fade"].is-inviewport { transform: rotate(180deg); opacity: 1; }
 Scroll down... <div data-inviewport="fade"></div> <div data-inviewport="fade"></div>

除了删除事件侦听器(由于某种原因这似乎对您不起作用)之外,一个简单的更改是添加一个全局 boolean 标志,您在执行 animation 后切换一次。如果该标志为真,只需从褪色 function

像这样的东西应该可以工作或者至少非常接近

let animationHappened = false; // flag to keep track of animation

function fade() {
  // only add the visible class if the animation hasn't happened yet, else return early
  if (animationHappened) return;

  let animation = document.querySelectorAll('.fade');

  for (let i = 0; i < animation.length; i++) {
    let windowheight = window.innerHeight;
    let top = animation[i].getBoundingClientRect().top;
    if (top < windowheight) {
      animation[i].classList.add('visible');
    } else {
      animation[i].classList.remove('visible');
    }
  }
  animationHappened = true;
}

只要animationHappened没有在代码中的其他任何地方再次设置为false ,这种方式的fade就应该只设置一次动画。

首先,在每次滚动时都执行querySelectorAll是非常低效的,所以假设所有这些元素总是存在,让我们立即抓住它们。

我们可以将节点列表变成一个数组,这样我们就可以像 go 一样轻松地删除项目。当一个元素可见时,我们只需添加可见的 class 并将其从数组中删除。 然后当数组为空时,只需删除侦听器。

要使项目再次不可见,我们可以将可见项目推送到第二个数组并执行类似的过程。 我们只在所有项目淡入然后淡出后才删除该侦听器。

 const fadeInElements = Array.from(document.querySelectorAll('.fade')); const makeInvisible = []; let fadeInEmpty = false; window.addEventListener('scroll', fadeIn); window.addEventListener('scroll', fadeOut); function fadeIn() { const windowheight = window.innerHeight; for (let i = 0; i < fadeInElements.length; i++) { const element = fadeInElements[i]; const topOfElement = element.getBoundingClientRect().top; if (topOfElement < windowheight) { element.classList.add('visible'); makeInvisible.push(element); fadeInElements.splice(i, 1); if (fadeInElements.length === 0) { window.removeEventListener('scroll', fadeIn); fadeInEmpty = true; } } } } function fadeOut() { const windowheight = window.innerHeight; for (let i = 0; i < makeInvisible.length; i++) { const element = makeInvisible[i]; const topOfElement = element.getBoundingClientRect().top; if (topOfElement >= windowheight) { element.classList.remove('visible'); makeInvisible.splice(i, 1); if (makeInvisible.length === 0 && fadeInEmpty) window.removeEventListener('scroll', fadeOut); } } }
 div { margin-top: 100px; }.fade { opacity: 0; }.visible { transition: opacity 0.9s ease-in; opacity: 1; }
 <div>1</div> <div class="fade">2</div> <div class="fade">3</div> <div class="fade">4</div> <div class="fade">5</div> <div class="fade">6</div> <div class="fade">7</div> <div class="fade">8</div> <div class="fade">9</div> <div class="fade">10</div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM