2009-11-18 3 views
3

나는 계속해서 previous post을 사용하고 있지만 다른 접근 방식을 취하고 실제 코드가 더 많기 때문에 새로운 스레드를 열어 보았습니다. 어쨌든, 나는 창을 통해 div 스크롤하는 무한 루프를 얻으려고 노력하고있다. (다른 포스트는 이미지를 가지고 있으며, 아래의 코드는 작동한다.)divs와 jquery가 포함 된 연속 루프

<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 파일로 저장하고 브라우저에서 실행하면 좋을 것입니다. 나는 이것에 잠시 동안 고생했다. 그래서 어떤 도움도 굉장 할 것이다. 감사.

답변

4

당신이

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

checkEdge() 같은 콜백을 설정해야합니다 작업 솔루션 http://jsbin.com/uceqi (단지 붙여 복사 코드) 여기를하지 checkEdge

확인


여기에 중괄호를 사용하지 않으면 실제로 차이가납니다. 교정기 버전은 애니메이션에 한 번하는 (애니메이션를 시작하기 전에이 checkEdge을 실행 현실에 정직하게 checkEdge()을 실행합니다. $...animte(..) 문 자체가 실행도 animate() 전에 도달하면 checkEdge() 함수가 호출된다. checkEdge 함수가 전달되도록 할 것 매개 변수로, 일반적으로 올바른 방법).

중괄호가없는 버전은 선택기와 일치하는 요소의 수에 대해 checkEdge 번만 실행합니다. 이 경우 6 번.

기술적으로 말하면 애니메이션 요소 당 한 번 콜백을 실행하고 AFTER 애니메이션을 적용하면 올바른 방식이 될 것입니다. 그러나 일단 checkEdge을 실행하면 저자가 의도 한 바가 분명하지 않습니다. (div보다 더 많은 부분을 확인하십시오. checkEdge). 또한 모든 div의 이상 당신 루프로 여러 번 심각한 지체의 원인

6divs는 -> 애니메이션 6 배 콜백 -> 콜백 checkEdge()==> 36 배 실행 익명 함수의 모든 div의를 통해 루프 발사!

그래서 실제 문제는 콜백이 동시에 6 회 실행된다는 것입니다. 따라서 우리에게는 경쟁 조건이 있으며 애니메이션이 엉망입니다. 여러 checkEdge() 호출이 div의 위치를 ​​변경하는 동시에 동시에 작동합니다. animation-speedsetInterval (shiftLeft)의 간격이 동일하기 때문에

는 그러나 만이 알 수 있습니다. 그것들은 다를 것입니다 ((interval + ~ 1000ms)> 애니메이션 속도). 그러면 올바르게 작동 할 것입니다. 물론 애니메이션은 유동적이지 않습니다. shitfLeft()은 애니메이션이 중단 된 후 1 초 후에 시작됩니다.

이 샘플 http://jsbin.com/iwapi3에서 중괄호없이 버전을 사용할 때 어떤 일이 발생하는지 확인할 수 있습니다. 언젠가는 기다려주십시오. checkEdge()에 대한 카운터는 3 초마다 7 건씩 증가합니다. 경우에 따라 애니메이션이 부분적으로 작동하고 일부 div가 목록의 끝으로 (때로는) 이동한다는 것을 알 수 있습니다.

언젠가 버튼을 클릭하고 몇 번 실행 한 후에 중괄호를 사용하여 버전이 엉망으로 정렬되는 것을 지켜보십시오.하지만 색상의 올바른 순서는 물론 엉망입니다. 애니메이션 당 한 번만 checkEdge()이라고 부릅니다. (잠시 후 버튼을 치면 일부 콜백이 아직 파이프에 남아 있기 때문에 +7이 추가됩니다)

+0

흠, 문법이 달라 지나요? iirc 전에 큰 성공을 거둔 버팀대없이 버전을 사용했습니다. 이 경우 실제로는 – Karsten

+0

입니다. 설명은 내 대답에 나와 있습니다. 기술적으로 솔루션이 정확하고 솔루션이 올바르지 않습니다. 자세한 내용은 답변 확인을 참조하십시오. – jitter

+0

@ 지터 : 설명 해 주셔서 감사합니다. – Karsten

0

JavaScript 실행은 애니메이션 기능의 3000msec가 소비 될 때까지 기다리지 않습니다. animate 함수를 시작하지만 checkEdge() 함수로 이동합니다 (0-1msec 후). checkEdge()에서 상태를 확인하지 않아도됩니다.

이 문제를 방지하려면 checkEdge() 함수를 animate 함수에 콜백으로 추가해야합니다.이 함수는 3000ms 후에 정확히 실행됩니다.

이 시도 :

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

답장을 보내 주셔서 감사합니다. 귀하의 솔루션을 시도했지만, 지금은 이상한 및 일관성없는 일들이 내 코드에서 일어나고 있습니다. – sa125

관련 문제