连续环带的div和jQuery
-
20-09-2019 - |
题
我继续一个以前的帖子,但我认为因为它采用了不同的方法,并有更多的实际的代码我会打开一个新的线程。无论如何,我试图让一个无限循环使用的div滚动的窗口下(其他职位有图像,及以下作品的代码)去。
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Bleh...</title>
<style type="text/css" media="screen">
body {
padding: 0;
text-align: center;
}
#container {
width: 1000px;
padding: 10px;
border: 1px solid #bfbfbf;
margin: 0 auto;
position: relative;
}
#window {
width: 400px;
height: 100px;
padding: 10px;
border: 3px solid #666;
margin: 0 auto;
}
.box {
height: 100px;
width: 100px;
border: 1px solid #666666;
position: absolute;
z-index: -1;
}
.red { background-color: #ff6868;}
.green { background-color: 7cd980;}
.blue { background-color: #5793ea;}
.yellow { background-color: #f9f69e;}
.purple { background-color: #ffbffc;}
.cyan { background-color: #bff3ff;}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
$(window).load(function() {
arrangeBoxes();
setInterval('shiftLeft()', 3000);
});
// arrange the boxes to be aligned in a row
function arrangeBoxes() {
$('.box').each( function(i, item) {
var position = $('#window').position().left + 3 + i * ( $(item).width() + 10 );
$(item).css('left', position+'px')
});
}
// shifts all the boxes to the left, then checks if any left the window
function shiftLeft() {
$('.box').animate({'left' : "-=100px"}, 3000, 'linear');
checkEdge();
}
// returns the new location for the box that exited the window
function getNewPosition() {
return $('.box:last').position().left + $('.box:last').outerWidth() + 10;
}
// if the box is outside the window, move it to the end
function checkEdge() {
var windowsLeftEdge = $('#window').position().left;
$('.box').each( function(i, box) {
// right edge of the sliding box
var boxRightEdge = $(box).position().left + $(box).width();
// position of last box + width + 10px
var newPosition = getNewPosition();
if ( $(box).attr('class').indexOf('red') >=0 ) {
console.log('box edge: ' + boxRightEdge + ' window edge: ' + windowsLeftEdge + ' new pos: ' +newPosition);
}
if ( parseFloat(boxRightEdge) < parseFloat(windowsLeftEdge) ) {
$(box).css('left', newPosition);
$(box).remove().appendTo('#window');
first = $('.box:first').attr('class');
console.log('first is ' + first);
}
});
}
</script>
</head>
<body id="index">
<div id="container">
<div id="window">
<div class="box red"></div>
<div class="box green"></div>
<div class="box blue"></div>
<div class="box yellow"></div>
<div class="box purple"></div>
<div class="box cyan"></div>
</div>
</div>
</body>
</html>
总之,问题是,我可以向左移动框,但我不能让领先的框弹出回线的末端,当我跑了整个事情。当我单独运行的每个功能(使用萤火虫) -
>> $('.box').animate({'left' : "-=100px"}, 3000, 'linear');
>> checkEdge()
它的伟大工程。当我把它们放在一起,我只是得到连续运动从右到左,直到箱子离开屏幕,因此它必须是它们之间如何相互作用。我希望这是有道理的(如果不是,保存上面的代码块作为一个HTML文件,然后在浏览器中运行它)。我一直停留在这一段时间,所以任何帮助将是真棒。感谢。
解决方案
您需要设置这样的回调
$('.box').animate({'left' : "-=100px"}, 3000, 'linear', checkEdge());
checkEdge()
不checkEdge
检查这里工作液 http://jsbin.com/uceqi (只需复印件粘贴代码)
这实际上是有差别,如果你离开括号之遥。用括号中的版本每个动画执行一次checkEdge()
(要在现实中诚实它执行checkEdge
前的动画开始即可。当达到checkEdge()
声明$...animte(..)
本身执行之前也animate()
function被调用。checkEdge
会导致要传递作为参数,通常是正确的路要走)函数。
没有括号中的版本,用于与选择器匹配元素的数量执行一次checkEdge
。在这种情况下的6倍。
所以,从技术上讲你的做法是正确的,因为这将每个动画元素启动一次回调和在动画。
但在执行checkEdge
一旦这显然不是作者的意图(检查checkEdge
遍历的div)。而且还造成了严重的滞后,你多次循环对所有的div
6divs动画->
6X回调烧制->
回调遍历所有div ==>
在checkEdge()
36X执行匿名函数!!
所以实际的问题是,回调函数被同时发射6倍和所有。因此,我们有一个竞争条件和动画弄乱了。由于几个checkEdge()
电话上重新定位的div同时工作。
但是,你只注意到这一点,因为animation-speed
和setInterval
的间隔(shiftLeft)是相同的。他们将是不同的((间隔+〜1000毫秒)>动画速度),那么它会正常工作了。但当然动画不会是流体。由于动画停止后shitfLeft()
将火1秒。
您可以检查此样本 http://jsbin.com/iwapi3 这说明当使用会发生什么版本没有括号。等待一段时间和checkEdge()
计数器调用由7分每3秒增加。您还会注意到,在某些情况下,动画部分的工作原理和一些div被移回至列表(有时)。
在某个时候按一下按钮,观看用大括号的版本几运行后如何排序惹出来(但现在颜色的正确顺序是当然搞砸了的)。而只有每个动画调用checkEdge()
一次。 (击中按钮后不久,你会得到另一个+7一些回调仍然在管)
其他提示
JavaScript执行不等待,直到你的动画功能的3000msec都花了。它开始的动画功能,但也就那么(后0-1毫秒)到您的checkEdge()函数的举动。你不检查在checkEdge(的状态),你可能想。
要防止这种情况,你应该添加您的checkEdge()函数作为回调的动画功能,将这些3000ms后究竟执行它。
尝试这种情况:
$('.box').animate({'left' : "-=100px"}, 3000, 'linear', checkEdge);