带有 div 和 jquery 的连续循环 [英] continuous loop with divs and jquery

查看:28
本文介绍了带有 div 和 jquery 的连续循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在继续上一篇文章,但我认为我会打开一个新线程,因为它采用不同的方法并且有更多实际代码.无论如何,我正在尝试让 div 滚动通过一个窗口进行无限循环(另一篇帖子有一个图像,下面的代码有效).

I'm continuing a previous post, but I thought I'd open a new thread since it takes a different approach and has more actual code. Anyway, I'm trying to get an infinite loop going with divs scrolling through a window (the other post has an image, and the code below works).

<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>

无论如何,问题是我可以让框向左移动,但是当我运行整个过程时,我无法让前导框弹回到行尾.当我分别运行每个函数时(使用萤火虫) -

Anyway, the problem is that I can get the boxes to move left, but I can't get the leading box to pop back to the end of the line when I run the whole thing. When I run each function separately (using firebug) -

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

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

It works great. When I put them together, I just get continuous motion right-to-left until the boxes leave the screen, so it must be how they interact. I hope this makes sense (if not, save the above code block as an html file and run it in a browser). I've been stuck on this for a while, so any help will be awesome. Thanks.

推荐答案

需要这样设置回调

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

checkEdge() 不是 checkEdge

在此处查看可行的解决方案 http://jsbin.com/uceqi(只需复制粘贴您的代码)

Check here for a working solution http://jsbin.com/uceqi (just copy pasted your code)

在这里,如果您不使用牙套,实际上会有所不同.带大括号的版本在每个动画中执行一次 checkEdge()(老实说,实际上它执行 checkEdge 在动画开始之前.$...animte(..) 语句到达时,甚至在 animate() 本身执行之前调用 checkEdge()函数.checkEdge 将导致函数作为参数传入,通常是正确的方法).

Here it actually makes a difference if you leave the braces away. The version with braces executes checkEdge() once per animation (to be honest in reality it executes checkEdge BEFORE the animation starts. The checkEdge()function is called when the $...animte(..) statement is reached even before animate() itself executes. checkEdge would cause the function to be passed in as parameter, normally the correct way to go).

不带大括号的版本对与选择器匹配的元素个数执行一次checkEdge.在这种情况下 6 次.

The version without braces executes checkEdge once for the number of elements matched with the selector. In this case 6 times.

所以从技术上讲,您的方法是正确的,因为它会在每个动画元素和 AFTER 动画之后触发一次回调.但是执行 checkEdge 显然不是作者想要的(检查 checkEdge 中的 div 循环).当您在所有 div 上循环多次时也会导致严重滞后

So technically speaking your approach would be correct as it would fire the callback once per animated element and AFTER the animation. But executing checkEdge once this obviously isn't what the author intended (check loop over divs in checkEdge). And also causes serious lagging as you loop several times over all divs

6divs 动画 -> 6x 回调触发 -> 回调循环遍历所有 div ==> 36x 匿名函数执行checkEdge()!!

6divs animated -> 6x callback fired -> callback loops over all divs ==> 36x execution of anonymous function in checkEdge()!!

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

So the actual problem is that the callback gets fired 6x and all at the same time. Thus we have a race condition and the animation messes up. As several checkEdge() calls work concurrently on repositioning the divs.

但您只注意到这一点是因为 animation-speedsetInterval (shiftLeft) 中的间隔是相同的.它们会有所不同((间隔+〜1000ms)>动画速度)那么它也可以正常工作.但当然动画不会是流畅的.因为 shitfLeft() 会在动画停止后 1 秒触发.

But you only notice this because the animation-speed and the interval in setInterval (shiftLeft) are identical. Would they be different ((interval +~1000ms) > animation-speed) then it would work correctly too. But of course the animation wouldn't be fluid. As shitfLeft() would fire 1s after the animation stopped.

您可以查看此示例 http://jsbin.com/iwapi3,它说明了使用没有大括号的版本.等待一段时间,checkEdge() 调用的计数器每 3 秒增加 7.您还会注意到,在某些情况下,动画部分起作用,并且一些 div 被移回列表末尾(有时).

You can check this sample http://jsbin.com/iwapi3 which illustrates what happens when use the version without braces. Wait for sometime and the counter for checkEdge() calls increases by 7 every 3s. You will also notice that in some cases the animation partially works and some divs are moved back to end of the list (sometimes).

一段时间后单击按钮并观察带有大括号的版本在运行几次后如何整理混乱(但现在正确的颜色顺序当然是混乱的).每个动画只调用一次 checkEdge() .(点击按钮后不久,您将获得另一个 +7,因为一些回调仍在处理中)

After sometime click the button and watch how the version with braces sorts the mess out after a few runs (but by now the correct order of the color is of course messed up). And only calls checkEdge() once per animation. (Shortly after hitting the button you will get another +7 as some callbacks are still in the pipe)

这篇关于带有 div 和 jquery 的连续循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆