仅当使用香草javascript将网页的不同部分滚动到视图中时,我才希望为其设置动画。这就是我的代码现在的样子
<script>
let target = document.querySelector("#who-we-are");
let service = document.querySelector("#what-we-do");
function animateAboutUs() {
if (target.scrollIntoView) {
document.querySelector("#who").classList.add("fadeIn");
}
}
function animateServiceList() {
if (service.scrollIntoView) {
document.querySelector("#service").classList.add("fadeIn");
}
}
window.onscroll = function() {
animateAboutUs();
animateServiceList();
};
</script>
这样做的问题在于,一旦用户开始向下滚动页面,service
部分就会获得动画效果,即使该页面尚未显示。
仅当将部分滚动到多个部分的视图中时,制作动画的正确方法是什么?
答案 0 :(得分:1)
一种现代的解决方案是使用Intersection Observer而不是监听滚动事件。
首先,您定义观察者:
var options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 0.1
}
var observer = new IntersectionObserver(callback, options);
.1的阈值表示callback()
函数在可见10%(或更多)时立即被调用。调整为您认为合适的位置。
如果省略root选项,则使用浏览器视口。
然后您观察以下项目:
var target = document.querySelector('.scrollItems');
observer.observe(target);
现在,只要目标达到为IntersectionObserver指定的阈值,就会调用该回调。
var callback = function(entries, observer) {
entries.forEach(entry => {
// this loops through each element that is visible, add your classes here
entry.addClass('fadeIn');
});
}
注意:如果您还需要支持较旧的浏览器,请there is a polyfill available.
答案 1 :(得分:0)
var $animation_elements = $('.animation-element');
var $window = $(window);
function check_if_in_view() {
var window_height = $window.height();
var window_top_position = $window.scrollTop();
var window_bottom_position = (window_top_position + window_height);
$.each($animation_elements, function() {
var $element = $(this);
var element_height = $element.outerHeight();
var element_top_position = $element.offset().top;
var element_bottom_position = (element_top_position + element_height );
//check to see if this current container is within viewport
if ((element_bottom_position >= window_top_position) &&
(element_top_position <= window_bottom_position)) {
$element.addClass('in-view');
} else {
$element.removeClass('in-view');
}
});
}
答案 2 :(得分:0)
这是使用querySelectorAll,getBoundingClientRect和eventListeners的另一种通用解决方案。
请参阅以下示例的注释:
document.querySelectorAll('.section').forEach(section => {
const rect = section.getBoundingClientRect(); // get position of section
if(rect.top < document.body.scrollTop + window.innerHeight){ // check initial if a section is in view
section.classList.add('fadeIn');
} else {
window.addEventListener("scroll", addClass(section, rect)); // add eventlistener
}
});
function addClass(element, rect) {
const offset = 100; // set an offset to the needed scrollposition (in px)
let handler = () => {
if(rect.top < document.body.scrollTop + window.innerHeight - offset){ // check if scrollposition is reached
element.classList.add('fadeIn');
window.removeEventListener('scroll', handler); // remove eventlistener
console.log(`reached section ${element.id}`);
}
};
return handler;
}
.section {
height: 100vh;
color: transparent;
text-align: center;
font-size: 100px;
}
.section.fadeIn {
color: #000 !important;
}
#one { background-color: yellow }
#two { background-color: green }
#three { background-color: orange }
#four { background-color: lightblue }
#five { background-color: grey }
<div class="section" id="one">Faded In!</div>
<div class="section" id="two">Faded In!</div>
<div class="section" id="three">Faded In!</div>
<div class="section" id="four">Faded In!</div>
<div class="section" id="five">Faded In!</div>