jquery CSS3-动画元素,如果在视口中可见(页面滚动)

hfyxw5xn  于 2023-08-04  发布在  jQuery
关注(0)|答案(3)|浏览(123)

我已经在我的html页面上的各种div元素中添加了CSS动画。但是所有的动画都同时播放&我看不到页面底部的动画。我如何在向下滚动页面时播放它们?

mkshixfv

mkshixfv1#

使用交集观察器API

IntersectionObserver API提供了一种异步观察目标元素与祖先元素或顶级文档的视口的交集中的更改的方法。
下面是一个当元素在视口中时触发classList toggle的示例:

const inViewport = (entries, observer) => {
  entries.forEach(entry => {
    entry.target.classList.toggle("is-inViewport", entry.isIntersecting);
  });
};

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:
document.querySelectorAll('[data-inviewport]').forEach(el => {
  Obs.observe(el, obsOptions);
});
[data-inviewport] { /* THIS DEMO ONLY */
  width:100px; height:100px; background:#0bf; margin: 150vh 0; 
}

/* inViewport */

[data-inviewport="scale-in"] { 
  transition: 2s;
  transform: scale(0.1);
}
[data-inviewport="scale-in"].is-inViewport { 
  transform: scale(1);
}

[data-inviewport="fade-rotate"] { 
  transition: 2s;
  opacity: 0;
}
[data-inviewport="fade-rotate"].is-inViewport { 
  transform: rotate(180deg);
  opacity: 1;
}
Scroll down...
<div data-inviewport="scale-in"></div>
<div data-inviewport="fade-rotate"></div>

观察者选项

要定义另一个父引用元素,请使用Observable options Object中的root选项。您还可以选择rootMargin和超级有用的threshold选项

const obsOptions = {
  // Default is null (Browser viewport). Set a specific parent element:
  root: document.querySelector('#someSpecificParent'),
  // add 40px inner "margin" area at which the observer starts to calculate:
  rootMargin: '40px', 
  // Default is 0.0 meaning the callback is called as soon 1 pixel is inside the viewport.  
  // Set to 1.0 to trigger a callback when 100% of the target element is inside the viewport,   
  // or i.e: 0.5 when half of the target element is visible:
  threshold: 0.5, 
};


请参阅另一个interesting use case that uses the IntersectionObserver API's threshold选项。
其他阅读:

使用 native IntersectionObserver API是解决此问题的**最有效的方法 *。
如果您想了解我们过去是如何解决类似需求的,请参阅this answer with a small custom plugin示例。

ltskdhd1

ltskdhd12#

仍然是JavaScript,但在这个版本中,你不需要监听滚动事件。速度和性能比每次检查一个对象是否在视口中要好得多。
点击这里:https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
通过交集观察器,可以定义元素可见时的回调。
选项:
root:null <<如果你想让它在你的viewport(可见区域)内,设置为null
threshold:0.3 <<表示30%的可见度。如果设置为0.3,则在可见性达到至少30%时调用一次回调,并且在可见性低于30%时调用一次回调。

function callbackFunc(entries, observer)
{
  entries.forEach(entry => {
    var txt = entry.target.id + " visibility: " + entry.isIntersecting;
    
    document.getElementById('log').appendChild(document.createTextNode(txt));
    document.getElementById('log').appendChild(document.createElement("br"));
  });
}

let options = {
    root: null,
    rootMargin: '0px',
    threshold: 0.3
  };

let observer = new IntersectionObserver(callbackFunc, options);

observer.observe(document.getElementById('firstBlock'));
observer.observe(document.getElementById('secondBlock'));
#firstBlock {
  width: 50vw;
  height: 80vh;
  background: red;
}

#secondBlock {
  width: 50vw;
  height: 80vh;
  background: blue;
}

#log {
  width: 200px;
  height: 80vh;
  position: fixed;
  right: 0px;
  top: 10px;
  overflow: auto;
}
First Block:
<div id='firstBlock'> </div>
<br><br><br>
Second Block:
<div id='secondBlock'> </div>
<div id='log'>Log: </div>
jpfvwuh4

jpfvwuh43#

另一种方法是使用滚动事件侦听器

document.addEventListener("DOMContentLoaded", function(event) {
    document.addEventListener("scroll", function(event) {
        const animatedBoxes = document.getElementsByClassName("animated-box");
        const windowOffsetTop = window.innerHeight + window.scrollY;

        Array.prototype.forEach.call(animatedBoxes, (animatedBox) => {
            const animatedBoxOffsetTop = animatedBox.offsetTop;

            if (windowOffsetTop >= animatedBoxOffsetTop) {
                addClass(animatedBox, "fade-in");
            }
        });
    });
});

function addClass(element, className) {
    const arrayClasses = element.className.split(" ");
    if (arrayClasses.indexOf(className) === -1) {
        element.className += " " + className;
    }
}
.animated-box {
  width: 150px;
  height: 150px;
  margin-top: 100vh;
  background: blue;
}

.fade-in {
    -webkit-animation: fade-in 1.2s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
            animation: fade-in 1.2s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}

 @-webkit-keyframes fade-in {
  0% {
    -webkit-transform: translateY(50px);
            transform: translateY(50px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0);
            transform: translateY(0);
    opacity: 1;
  }
}
@keyframes fade-in {
  0% {
    -webkit-transform: translateY(50px);
            transform: translateY(50px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0);
            transform: translateY(0);
    opacity: 1;
  }
}
<div>
  Start scrolling down...
  
  <div class="animated-box">

  </div>
        
  <div class="animated-box">
        
  </div>

  <div class="animated-box">
  
  </div>
  
  <div class="animated-box">
  
  </div>
  
  <div class="animated-box">
  
  </div>
</div>

相关问题