jQuery 清除超时问题
jQuery clearTimeout problems
我想延迟一小会儿一个一个地显示一些元素。为此,我检查 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>
滚动事件会在用户滚动时触发很多次,并且每次您设置另一个超时时,都会覆盖旧超时的 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
}
}
我想延迟一小会儿一个一个地显示一些元素。为此,我检查 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>
滚动事件会在用户滚动时触发很多次,并且每次您设置另一个超时时,都会覆盖旧超时的 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
}
}