您的尝试无效的原因是因为两个动画(淡入和淡出)相互对抗。
就在对象变得可见之前,它仍然不可见,因此淡出动画会运行。然后,在同一对象变得可见的几分之一秒后,淡入动画将尝试运行,但淡出仍在运行。所以他们会互相对抗,你什么也看不到。
最终对象会变得可见(大部分时间),但这需要一段时间。如果您使用滚动条按钮上的箭头按钮向下滚动,动画就会起作用,因为您将使用更大的增量滚动,从而减少滚动事件。
解释够了,解决方案(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>
(小提琴:http : //jsfiddle.net/eLwex993/2/)
- 我裹着淡入代码行的如果子句中:
if ($(this).css("opacity")==0) {...}
。这可确保对象仅在opacity
is时淡入0
。淡出也一样。这可以防止淡入和淡出相互影响,因为现在在一个对象上只同时运行两者之一。
- 我换
.animate()
到.fadeTo()
。它是 jQuery 的不透明度专用函数,编写起来要短得多,而且可能比动画更轻。
- 我换
.position()
到.offset()
。这总是相对于身体计算,而位置是相对于父级的。对于你的情况,我相信抵消是要走的路。
- 我换
$(window).height()
到$(window).innerHeight()
。根据我的经验,后者更可靠。
- 直接在滚动处理程序之后,我在页面加载时调用该处理程序一次
$(window).scroll();
。现在您可以为页面上所有需要的对象提供.fade
类,并且在页面加载时不可见的对象将立即淡出。
- 我
#container
从 HTML 和 CSS 中删除,因为(至少对于这个答案)它不是必需的。(我想也许您需要 ,height:2000px
因为您使用了.position()
而不是.offset()
,否则我不知道。当然可以将它留在您的代码中。)
更新
如果你想比其他的不透明度值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>
(小提琴:http : //jsfiddle.net/eLwex993/3/)
- 我在 if 子句中添加了一个阈值,请参阅下面的说明。
- 我在函数开始时为 the
threshold
和 for创建了变量min/max
。在函数的其余部分,这些变量被引用。这样,如果您想再次更改这些值,只需在一个地方进行。
- 我还添加
|| pageLoad
了 if 子句。这对于确保所有对象在页面加载时淡化到正确的不透明度是必要的。pageLoad
是一个布尔值,在fade()
调用时作为参数发送。
我必须将淡入淡出代码放在 extra 中function fade() {...}
,以便在pageLoad
调用滚动处理程序时能够沿布尔值发送。
我没有看到任何其他方法可以做到这一点,如果有人这样做,请发表评论。
说明:您的小提琴中
的代码不起作用的原因是因为实际的不透明度值总是与您设置的值略有偏差。因此,如果您将不透明度设置为,则实际值(在本例中)为。这只是您必须通过跟踪和错误学习的那些小错误之一。这就是为什么这个if子句将无法正常工作:。0.3
0.300000011920929
if ($(this).css("opacity") == 0.3) {...}
我添加了一个阈值,以将这种差异考虑在内:== 0.3
成为<= 0.31
.
(我已将阈值设置为0.01
,当然可以更改,只要实际不透明度介于设置值和此阈值之间即可。)
运算符现在从 更改==
为<=
和>=
。
更新 2:
如果要根据元素的可见百分比淡化元素,请使用以下代码:
$(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>
(小提琴:http : //jsfiddle.net/eLwex993/5/)