我希望一个接一个地显示一些元素并且延迟很短。为此,我检查div是否在视口中。如果是,则显示元素。如果用户向下滚动以使div不再在视口中,则应清除setTimeout。但它似乎不起作用!您可以测试它...向下滚动几次然后向上滚动并查看问题。超时未被清除,元素显示混乱。
那我的错误在哪里?
<html>
<head>
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<style type="text/css">
.div1, .div2, .div3 {
opacity:0;
float:left;
width:300px;
height:300px;
font-size:80px;
margin:20px;
}
.show {
opacity:1;
}
</style>
</head>
<body>
<script>
jQuery(document).ready(function(){
recheck();
jQuery(window).scroll(function(){
recheck();
});
var timer1, timer2, timer3;
});
function recheck() {
if (jQuery('.box').is_on_screen()) {
timer1 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div1').addClass('show'); } },1000);
timer2 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div2').addClass('show'); } },3000);
timer3 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div3').addClass('show'); } },5000);
} else {
window.clearTimeout(timer1);
window.clearTimeout(timer2);
window.clearTimeout(timer3);
setTimeout(function(){ jQuery('.box div').removeClass('show'); },1);
}
}
jQuery.fn.is_on_screen = function(){
var win = jQuery(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
</script>
<div style="float:left;width:100%;height:3000px;">
<div class="box" style="float:left;border:3px solid red;">
<div class="div1" style="border:3px solid blue;background:#c4caf3;">1</div>
<div class="div2" style="border:3px solid orange;background:#fbe7cb;">2</div>
<div class="div3" style="border:3px solid green;background:#d6f1d4;">3</div>
</div>
</div>
</body>
</html>
答案 0 :(得分:1)
滚动事件会在用户滚动时多次触发,每次设置另一个超时时,都会覆盖旧超时的ID。您需要确保只设置一次定时器。
var timer1, timer2, timer3, setTimers = false; // Move these outside the ready function
function recheck() {
if (jQuery('.box').is_on_screen()) {
if(!setTimers) { // Only set the timers once
setTimers = true;
timer1 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div1').addClass('show'); } },1000);
timer2 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div2').addClass('show'); } },3000);
timer3 = setTimeout(function(){ if (jQuery('.box').is_on_screen()) { jQuery('.box .div3').addClass('show'); } },5000);
}
} else {
window.clearTimeout(timer1);
window.clearTimeout(timer2);
window.clearTimeout(timer3);
setTimeout(function(){ jQuery('.box div').removeClass('show'); },1);
setTimers = false; // Allow setting timers again
}
}