用div和jquery连续循环

时间:2009-11-18 07:38:33

标签: jquery animation slider continuous motion

我正在继续previous post,但我想我会打开一个新线程,因为它采用了不同的方法并且有更多的实际代码。无论如何,我试图得到一个无限循环,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>

无论如何,问题是我可以让盒子向左移动,但是当我运行整个东西时,我无法让前导框弹回到行尾。当我单独运行每个功能时(使用firebug) -

>> $('.box').animate({'left' : "-=100px"}, 3000, 'linear');
>> checkEdge()

效果很好。当我把它们组合在一起时,我只是从左到右连续运动,直到盒子离开屏幕,因此它们必须是它们如何相互作用。我希望这是有道理的(如果没有,将上面的代码块保存为html文件并在浏览器中运行)。我已经坚持了一段时间,所以任何帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:4)

您需要像这样设置回调

$('.box').animate({'left' : "-=100px"}, 3000, 'linear', checkEdge());

checkEdge()不是checkEdge

点击此处查看有效的解决方案http://jsbin.com/uceqi(只需复制粘贴代码)


如果你把牙箍放开,它实际上会有所不同。带有大括号的版本每个动画执行checkEdge()一次(说实话,它实际上在动画开始之前执行checkEdge checkEdge()函数在{甚至在$...animte(..)本身执行之前就已达到{1}}语句。animate()会导致函数作为参数传入,通常是正确的方法。

对于与选择器匹配的元素数,没有大括号的版本执行checkEdge一次。在这种情况下6次。

从技术上讲,你的方法是正确的,因为它会在每个动画元素和 AFTER 动画时触发一次回调。 但是执行checkEdge一旦这显然不是作者的意图(检查checkEdge中的div循环)。当你在所有div上循环几次时,也会造成严重的滞后

6divs动画checkEdge 6x回调在所有div上->回调循环-> 36x执行==>中的匿名函数!!

所以实际问题是回调被同时触发了6次并且全部被触发。因此,我们有一个竞争条件和动画混乱。由于多个checkEdge()调用同时用于重新定位div。

但是你只注意到这一点,因为checkEdge()animation-speed(shiftLeft)中的间隔是相同的。它们会不同((间隔+ ~1000ms)>动画速度)然后它也能正常工作。但当然动画不会流畅。动画停止后,setInterval将触发1秒。

您可以查看此示例http://jsbin.com/iwapi3,其中说明了使用不带大括号的版本时会发生什么。等待一段时间,shitfLeft()呼叫的计数器每3秒增加7。您还会注意到,在某些情况下,动画部分工作,一些div被移回列表的末尾(有时)。

一段时间后,点击按钮,观看带有大括号的版本如何在几次运行后对混乱进行排序(但现在正确的颜色顺序当中搞砸了)。并且每个动画只调用一次checkEdge()。 (按下按钮后不久,你会得到另一个+7,因为一些回调仍在管道中)

答案 1 :(得分:0)

JavaScript执行不会等到你的动画函数花费3000毫秒。它启动动画功能,但然后(在0-1毫秒后)移动到你的checkEdge()函数。您不需要检查checkEdge()中的状态。

为了防止这种情况,您应该将checkEdge()函数作为回调函数添加到animate函数中,该函数将在3000ms之后执行。

试试这个:

$('.box').animate({'left' : "-=100px"}, 3000, 'linear', checkEdge);