[英]Fade In on Scroll Down, Fade Out on Scroll Up - based on element position in window
I'm trying to get a series of elements to fade in on scroll down when they are fully visible in the window.当它们在窗口中完全可见时,我试图让一系列元素在向下滚动时淡入。 If I keep scrolling down, I do not want them to fade out, but if I scroll up, I do want them to fade out.
如果我继续向下滚动,我不希望它们淡出,但如果我向上滚动,我确实希望它们淡出。
This is the closest jsfiddle I've found.这是我找到的最接近的 jsfiddle。 http://jsfiddle.net/tcloninger/e5qaD/
http://jsfiddle.net/tcloninger/e5qaD/
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll( function(){
/* Check the location of each desired element */
$('.hideme').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 it */
if( bottom_of_window > bottom_of_object ){
$(this).animate({'opacity':'1'},500);
}
});
});
});
It does exactly what I want on scroll down, but I also want the elements to fade out if I scroll up past them.它在向下滚动时完全符合我的要求,但我也希望元素在我向上滚动时淡出它们。
I tried this with no luck.我没有运气就试过这个。
if( bottom_of_window > bottom_of_object ){
$(this).animate({'opacity':'1'},500);
} else {
$(this).animate({'opacity':'0'},500); }
Thanks so much for taking the time to look at this.非常感谢您花时间看这个。
The reason your attempt wasn't working, is because the two animations (fade-in and fade-out) were working against each other.您的尝试无效的原因是因为两个动画(淡入和淡出)相互对抗。
Right before an object became visible, it was still invisible and so the animation for fading-out would run.就在对象变得可见之前,它仍然不可见,因此淡出动画会运行。 Then, the fraction of a second later when that same object had become visible, the fade-in animation would try to run, but the fade-out was still running.
然后,在同一对象变得可见的几分之一秒后,淡入动画将尝试运行,但淡出仍在运行。 So they would work against each other and you would see nothing.
所以他们会互相对抗,你什么也看不到。
Eventually the object would become visible (most of the time), but it would take a while.最终对象将变得可见(大部分时间),但这需要一段时间。 And if you would scroll down by using the arrow-button at the button of the scrollbar, the animation would sort of work, because you would scroll using bigger increments, creating less scroll-events.
如果您使用滚动条按钮上的箭头按钮向下滚动,动画就会起作用,因为您将使用更大的增量滚动,从而减少滚动事件。
Enough explanation, the solution (JS, CSS, HTML):解释够了,解决方案(JS、CSS、HTML):
$(window).on("load",function() { $(window).scroll(function() { var windowBottom = $(this).scrollTop() + $(this).innerHeight(); $(".fade").each(function() { /* Check the location of each desired element */ var objectBottom = $(this).offset().top + $(this).outerHeight(); /* If the element is completely within bounds of the window, fade it in */ if (objectBottom < windowBottom) { //object comes into view (scrolling down) if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);} } else { //object goes out of view (scrolling up) if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);} } }); }).scroll(); //invoke scroll-handler on page-load });
.fade { margin: 50px; padding: 50px; background-color: lightgreen; opacity: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <div> <div class="fade">Fade In 01</div> <div class="fade">Fade In 02</div> <div class="fade">Fade In 03</div> <div class="fade">Fade In 04</div> <div class="fade">Fade In 05</div> <div class="fade">Fade In 06</div> <div class="fade">Fade In 07</div> <div class="fade">Fade In 08</div> <div class="fade">Fade In 09</div> <div class="fade">Fade In 10</div> </div>
if ($(this).css("opacity")==0) {...}
.if ($(this).css("opacity")==0) {...}
。 This makes sure the object is only faded in when the opacity
is 0
.opacity
为0
时淡入。 Same goes for fading out..animate()
to .fadeTo()
..animate()
更改为.fadeTo()
。 It's jQuery's specialized function for opacity, a lot shorter to write and probably lighter than animate..position()
to .offset()
..position()
更改为.offset()
。 This always calculates relative to the body, whereas position is relative to the parent.$(window).height()
to $(window).innerHeight()
.$(window).height()
改为$(window).innerHeight()
。 The latter is more reliable in my experience.$(window).scroll();
$(window).scroll();
调用该处理程序一次$(window).scroll();
. .fade
class, and objects that should be invisible at page-load, will be faded out immediately..fade
类,并且在页面加载时不可见的对象将立即淡出。#container
from both HTML and CSS, because (at least for this answer) it isn't necessary.#container
,因为(至少对于这个答案)它不是必需的。 (I thought maybe you needed the height:2000px
because you used .position()
instead of .offset()
, otherwise I don't know. Feel free of course to leave it in your code.) height:2000px
因为你使用了.position()
而不是.offset()
,否则我不知道。当然可以把它留在你的代码中。)If you want opacity values other than 0
and 1
, use the following code:如果您想要
0
和1
以外的不透明度值,请使用以下代码:
$(window).on("load",function() { function fade(pageLoad) { var windowBottom = $(window).scrollTop() + $(window).innerHeight(); var min = 0.3; var max = 0.7; var threshold = 0.01; $(".fade").each(function() { /* Check the location of each desired element */ var objectBottom = $(this).offset().top + $(this).outerHeight(); /* If the element is completely within bounds of the window, fade it in */ if (objectBottom < windowBottom) { //object comes into view (scrolling down) if ($(this).css("opacity")<=min+threshold || pageLoad) {$(this).fadeTo(500,max);} } else { //object goes out of view (scrolling up) if ($(this).css("opacity")>=max-threshold || pageLoad) {$(this).fadeTo(500,min);} } }); } fade(true); //fade elements on page-load $(window).scroll(function(){fade(false);}); //fade elements on scroll });
.fade { margin: 50px; padding: 50px; background-color: lightgreen; opacity: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <div> <div class="fade">Fade In 01</div> <div class="fade">Fade In 02</div> <div class="fade">Fade In 03</div> <div class="fade">Fade In 04</div> <div class="fade">Fade In 05</div> <div class="fade">Fade In 06</div> <div class="fade">Fade In 07</div> <div class="fade">Fade In 08</div> <div class="fade">Fade In 09</div> <div class="fade">Fade In 10</div> </div>
threshold
and for min/max
at the start of the function.threshold
和min/max
创建了变量。 In the rest of the function these variables are referenced.|| pageLoad
|| pageLoad
|| pageLoad
to the if-clause. || pageLoad
到 if 子句。 This was necessary to make sure all objects are faded to the correct opacity on page-load.pageLoad
is a boolean that is send along as an argument when fade()
is invoked. pageLoad
是一个布尔值,在调用fade()
时作为参数发送。function fade() {...}
, in order to be able to send along the pageLoad
boolean when the scroll-handler is invoked.function fade() {...}
,以便在调用滚动处理程序时能够沿着pageLoad
布尔值发送。 Explanation:解释:
The reason the code in your fiddle didn't work, is because the actual opacity values are always a little off from the value you set it to.您小提琴中的代码不起作用的原因是,实际的不透明度值总是与您设置的值略有不同。 So if you set the opacity to
0.3
, the actual value (in this case) is 0.300000011920929
.因此,如果您将不透明度设置为
0.3
,则实际值(在本例中)为0.300000011920929
。 That's just one of those little bugs you have to learn along the way by trail and error.这只是您必须通过跟踪和错误学习的那些小错误之一。 That's why this if-clause won't work:
if ($(this).css("opacity") == 0.3) {...}
.这就是这个 if 子句不起作用的原因:
if ($(this).css("opacity") == 0.3) {...}
。
I added a threshold, to take that difference into account: == 0.3
becomes <= 0.31
.我添加了一个阈值,以将这种差异考虑在内:
== 0.3
变为<= 0.31
。
(I've set the threshold to 0.01
, this can be changed of course, just as long as the actual opacity will fall between the set value and this threshold.) (我已将阈值设置为
0.01
,当然可以更改,只要实际不透明度介于设置值和此阈值之间即可。)
The operators are now changed from ==
to <=
and >=
.运算符现在从
==
更改为<=
和>=
。
If you want to fade the elements based on their visible percentage, use the following code:如果要根据元素的可见百分比淡化元素,请使用以下代码:
$(window).on("load",function() { function fade(pageLoad) { var windowTop=$(window).scrollTop(), windowBottom=windowTop+$(window).innerHeight(); var min=0.3, max=0.7, threshold=0.01; $(".fade").each(function() { /* Check the location of each desired element */ var objectHeight=$(this).outerHeight(), objectTop=$(this).offset().top, objectBottom=$(this).offset().top+objectHeight; /* Fade element in/out based on its visible percentage */ if (objectTop < windowTop) { if (objectBottom > windowTop) {$(this).fadeTo(0,min+((max-min)*((objectBottom-windowTop)/objectHeight)));} else if ($(this).css("opacity")>=min+threshold || pageLoad) {$(this).fadeTo(0,min);} } else if (objectBottom > windowBottom) { if (objectTop < windowBottom) {$(this).fadeTo(0,min+((max-min)*((windowBottom-objectTop)/objectHeight)));} else if ($(this).css("opacity")>=min+threshold || pageLoad) {$(this).fadeTo(0,min);} } else if ($(this).css("opacity")<=max-threshold || pageLoad) {$(this).fadeTo(0,max);} }); } fade(true); //fade elements on page-load $(window).scroll(function(){fade(false);}); //fade elements on scroll });
.fade { margin: 50px; padding: 50px; background-color: lightgreen; opacity: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <div> <div class="fade">Fade In 01</div> <div class="fade">Fade In 02</div> <div class="fade">Fade In 03</div> <div class="fade">Fade In 04</div> <div class="fade">Fade In 05</div> <div class="fade">Fade In 06</div> <div class="fade">Fade In 07</div> <div class="fade">Fade In 08</div> <div class="fade">Fade In 09</div> <div class="fade">Fade In 10</div> </div>
I tweaked your code a bit and made it more robust.我稍微调整了您的代码,使其更加健壮。 In terms of progressive enhancement it's probaly better to have all the fade-in-out logic in JavaScript.
在渐进增强方面,在 JavaScript 中拥有所有淡入淡出逻辑可能会更好。 In the example of myfunksyde any user without JavaScript sees nothing because of the
opacity: 0;
在 myfunksyde 的例子中,任何没有 JavaScript 的用户都看不到任何东西,因为
opacity: 0;
. .
$(window).on("load",function() {
function fade() {
var animation_height = $(window).innerHeight() * 0.25;
var ratio = Math.round( (1 / animation_height) * 10000 ) / 10000;
$('.fade').each(function() {
var objectTop = $(this).offset().top;
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
if ( objectTop < windowBottom ) {
if ( objectTop < windowBottom - animation_height ) {
$(this).html( 'fully visible' );
$(this).css( {
transition: 'opacity 0.1s linear',
opacity: 1
} );
} else {
$(this).html( 'fading in/out' );
$(this).css( {
transition: 'opacity 0.25s linear',
opacity: (windowBottom - objectTop) * ratio
} );
}
} else {
$(this).html( 'not visible' );
$(this).css( 'opacity', 0 );
}
});
}
$('.fade').css( 'opacity', 0 );
fade();
$(window).scroll(function() {fade();});
});
See it here: http://jsfiddle.net/78xjLnu1/16/在这里看到它: http : //jsfiddle.net/78xjLnu1/16/
Cheers, Martin干杯,马丁
I know it's late, but I take the original code and change some stuff to control easily the css.我知道已经晚了,但我采用了原始代码并更改了一些内容以轻松控制 css。 So I made a code with the addClass() and the removeClass()
所以我用 addClass() 和 removeClass() 做了一个代码
Here the full code : http://jsfiddle.net/e5qaD/4837/这里的完整代码: http : //jsfiddle.net/e5qaD/4837/
if( bottom_of_window > bottom_of_object ){
$(this).addClass('showme');
}
if( bottom_of_window < bottom_of_object ){
$(this).removeClass('showme');
Sorry this is and old thread but some people would still need this I guess,对不起,这是旧线程,但我想有些人仍然需要这个,
Note: I achieved this using Animate.css library for animating the fade.注意:我使用 Animate.css 库来实现淡入淡出动画。
I used your code and just added .hidden class (using bootstrap's hidden class) but you can still just define .hidden { opacity: 0; }
我使用了您的代码并刚刚添加了 .hidden 类(使用引导程序的隐藏类),但您仍然可以定义
.hidden { opacity: 0; }
.hidden { opacity: 0; }
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll( function(){
/* Check the location of each desired element */
$('.hideme').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 it */
if( bottom_of_window > bottom_of_object ){
$(this).removeClass('hidden');
$(this).addClass('animated fadeInUp');
} else {
$(this).addClass('hidden');
}
});
});
});
Another Note: Applying this to containers might cause it to be glitchy.另一个注意事项:将此应用于容器可能会导致它出现故障。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.