2012-05-15 5 views
2

BOLD은 업데이트를 나타냅니다.은 배열을 반복하는 러너를 구현합니다.

나는 배열이 steps이며, 그 내용은 액션과 요소가 연관된 객체입니다. 이와 같이 :

steps = [{action: 'click', element: <jQuery element>}, 
     {action: 'click', element: <jQuery element>}, ., ., N] 

주자를 구현하고 싶습니다. 그 작업은 배열의 각 요소를 실행하고 요소에 대해 특정 작업을 수행하는 것입니다. 각 단계는 연속적으로 수행되어야합니다. 그래서 예를 들어, 당신이있는 경우 :

steps = [{action: 'click', element: <jQuery element representing a button>}, 
      {action: 'click', element: <jQuery element representing an anchor tag>}] 

, run(steps, timeout) 실행, 각 단계를 실행하는 것입니다. step [0] .action은 step [0] .element에서 수행됩니다. step [0]이 단계 [1]에서 상호 작용할 dom 요소 (AJAX을 사용하여)를 만들 수 있으므로 주자는 특정 기간 (따라서 시간 초과)을 기다려야 만 dom을 폴링해야합니다 단계 [1]. 요소의 존재에 대해. 위의 예에서 steps가 JQuery와 객체의 단지 배열입니다

var run = function() { 
    $.each(steps, function(i, v) { 
     var interval = 25, 
      start = 0, 
      timeout = 3000; 
     var i = setInterval(function(timeout) { 
      start = start + interval; 
      console.log(start); 
      if ($(v).is(':visible')) { 
       v.click(); 
       console.log('clicked', v); 
       clearInterval(i); 
      } 
     }, interval); 
    }); 
}; 

참고 : 여기에

내가 지금까지 무엇을에서 거친 걸릴 수 있습니다. 아직 원하는 형식이 아닙니다 :

steps = [{action: 'click', element: <jQuery element>}, 
     {action: 'click', element: <jQuery element>}, ., ., N] 

따라야 할 '패턴'은 무엇입니까? 이를 처리하기 위해 지연된 객체를 사용해야합니까? 그것은 setTimeout, setInterval? 감사!

최종 구현

var run = function(steps, interval, timeout) { 
    var timer, 
     time = 0, 
     i = 0; 

    runSingle(steps[0]); 

    function abort() { 
     console.log("Run aborted"); 
    } 

    function runSingle(step) { 
     timer = setInterval(function() { 
      time += interval; 
      if ($(step.element).is(':visible') === true) { 
       clearInterval(timer); 
       time = 0; 
       $(step.element).trigger(step.action); 
       (i < (steps.length - 1)) && runSingle(steps[++i]); 
      } else if (time >= timeout) { 
       clearInterval(timer); 
       abort(); 
      } 
     }, interval); 
     console.log("Performed: ", step.action, "on", step.element) 
     if (i === (steps.length - 1)) console.log("Run successful"); 
    } 
} 
+0

합니까''JQuery와 선택기로 사용할 수있는 jQuery를 객체 또는 단지 CSS 선택기를 나타냅니다? 이미 jQuery 객체 인 경우 새 요소가 DOM에 추가되면 업데이트되지 않습니다. –

+0

Thanks. 현재 그것은 셀렉터를 사용하기 위해 업데이트해야하는 jquery 객체입니다. –

+0

선택기가 클래스 선택기이고 해당 클래스의 페이지에 다른 요소가 이미있는 경우 이전 함수가 이미 해당 작업을 완료했는지 어떻게 알 수 있습니까? –

답변

1

여기 있습니다. 나는 그것을 철저하게 테스트하지 않았습니다 :

var run = function(steps, interval) 
{ 
    var timer, 
     time = 0, timeout = 10000, 
     ciel = steps.length - 1, 
     i = 0; 

    run_single(steps[0]); 

    function run_single(item) 
    { 
     timer = setInterval(function() 
     { 
      var $el = $(item.selector); 

      time += interval; 

      if ($el.length) 
      { 
       clearInterval(timer); 
       time = 0; 

       $el.trigger(item.action); 

       i < ciel && run_single(step[ ++i ]); 
      } 
      else 
      { 
       if (time >= timeout) clearInterval(timer); 
      } 

     }, interval); 
    } 
}; 

var steps = [ 
    {action: 'click', selector: '#first'}, 
    {action: 'hover', selector: '#second'}, 
    {action: 'change', selector: '#third'} 
    // and so on... 
]; 

run(steps, 100); 

행동에 여기를 참조하십시오 http://jsfiddle.net/myaeh/

+0

차가움. 나는 그것을 가졌다. –

+0

@kennethkoontz - 코드를 약간 업데이트했는데 (필자는 거기에 몇 가지 생략이 있음), 바이올린을 포함 시켰습니다. 희망이 당신을 위해 ... –

+0

고마워! 귀하의 구현을 사용하여 문제를 해결했습니다. 나는 내가 한 일을 보여주기 위해 그 글을 업데이트했다. –

1

먼저 업의 v 변수가 배열에서 개체를 나타냅니다 귀하의 예제에서를 기록하고 따라서 그것은 의미가 v.click() 또는 $(v).is(':visible') 말을하지 않습니다 - 당신은 좋겠 v.element.click() 또는 v.element.is(':visible')이라고 말하고 싶습니다. 나타내는 캐릭터 라인이

$.each(steps, function(i, obj) { 
    obj.element[obj.action](); 
}); 

element 경우입니다 :

당신이 action이 jQuery를 법의 이름 인 문자열이 될 것을 의미하는 경우

element는이 같은 작업을 수행 할 수 있습니다, JQuery와 객체입니다 다음의 jQuery 개체를 만드는 데 사용되어야한다 선택기는 다음 action 예를 들어, 비동기 적으로 뭔가를 할 수없는 한

$.each(steps, function(i, obj) { 
    $(obj.element)[obj.action](); 
}); 

다음과 같은 경우는 D, 폴링 개념을 도입 할 필요가 없습니다 페이드 인, Ajax를 통해 요소 추가

예제에서 현재 단계로 진행할지 여부를 적용하는 유일한 기준은 현재 요소가 표시되는지 여부입니다. 그런 경우 당신은 이런 식으로 뭔가를 할 수 있습니다

var run = function(steps, delay, timeout) { 
      var i = 0, 
       nextStep = function() { 
        if (i < steps.length) { 
         var step = steps[i], 
          retryDelay = 25, 
          retryTotal = 0, 
          intervalId = setInterval(function() { 
           retryTotal += retryDelay; 
           var $el = $(step.element); 
           if ($el.is(':visible')) { 
           $el[step.action](); 
           clearInterval(intervalId); 
           i++; 
           setTimeout(nextStep, delay); 
           } else if (retryTotal >= timeout) { 
           clearInterval(intervalId); 
           } 
          }, retryDelay); 
        }; 
       } 
      nextStep(); 
}; 

run(steps, 50, 3000); 

run() 기능은 현재 요소의 표시 여부를 계속 확인하는 setInterval를 사용하는 nextStep() 함수를 정의합니다.일단 그것이 실행되면, 동작을 수행하고, 간격을 지우고, setTimeout을 통해 자신을 호출하여 다음 요소로 이동합니다.

폴링에 타임 아웃 개념을 적용하는 방법을 잘 모르겠다. 지정된 시간이 지난 후에 현재 요소가 표시되지 않으면 어떻게 할 것인가? 이전 단계에 따라 달라질 수 있으므로 다음 요소로 계속 진행할 수 없습니다. 간격을 지우고 모든 것을 취소 할 수 있고 이 아니라으로 전화를 걸어 nextStep()을 다시 호출 할 수 있습니다. 편집 : 나는 그 마지막 문장에 따라 작동하도록 코드를 업데이트했다.

+0

죄송합니다. 나는 요소들 중 하나를 클릭하는 것이 아약스 (Ajax)를 통해 dom 요소를 생성 할 수 있다는 것을 분명히해야했다. 나는 그 소식을 업데이트 할 것이다. –

+0

또한이 문제를 명확히하기 위해 "현재 요소가 지정된 시간 후에 표시되지 않으면 어떻게할까요?"라고 표시하면 주자가 중단됩니다. –

+0

그래, 주어진 단계가 끝나면 모든 것을 중단하는 코드를 약간 업데이트했다. 또한 각 단계의 'element' 속성이 jQuery _selector_가 아니라 jQuery _object_ 인 것으로 가정하여 이전 단계에서 ajax로 만든 요소의 선택기를 지정할 수 있도록 변경했습니다. – nnnnnn

관련 문제