setTimeout , setinterval 사용에대해서 질문

조회수 2254회

setTimeout(function() { $('.sub_txt_wp01').find('.a').addClass('on'); }, 1000); setTimeout(function() { $('.sub_txt_wp01').find('.b').addClass('on'); }, 2000); setTimeout(function() { $('.sub_txt_wp01').find('.ab_wp').removeClass('on'); }, 3000);

setTimeout(function() { $('.sub_txt_wp02').find('.c').addClass('on'); }, 4000); setTimeout(function() { $('.sub_txt_wp02').find('.d').addClass('on'); }, 5000); setTimeout(function() { $('.sub_txt_wp02').find('.cd_wp').removeClass('on'); }, 6000);

이런식으로 코드를 작성하면

a가 1초뒤 클래스명 on 부여 b가 2초뒤 클래스명 on 부여

a,b의 부모가 3초뒤에 클래스명 on 제거

c가 4초뒤 클래스명 on 부여 d가 5초뒤 클래스명 on 부여

c,d의 부모가 6초뒤에 클래스명 on 제거

이렇게잖아요? 근데 저렇게 딱한번씩만하고 끝나는데

저과정을 계속 반복하고싶으면 코드를 어떻게작성해야할까요..

  • (•́ ✖ •̀)
    알 수 없는 사용자

2 답변

  • 안녕하세요. 야무입니다. :-)

    지나가다 우연히 질문 내용을 확인하고 답변 드려봅니다.

    질문의 핵심은 반복 수행입니다. 즉, class 속성 on을 추가하거나, 제거하는 일련의 동작이 반복되는 것을 의미 하겠죠. 아마도 애니메이션을 처리하려고 질문한 것이 아닐까 생각됩니다.

    먼저 질문이 요구하는 결과부터 확인해보겠습니다.

    그런데 {#}hashcode는 GIF 이미지 삽입을 허용하지 않네요. 대신 GIF 이미지를 확인 가능한 링크 주소를 남깁니다.

    i.imgur.com/BrpteEr.gif

    그리고 완성된 코드는 다음과 같습니다. 코드에 대한 자세한 설명은 아래 기술 했으니 코드를 살펴보고 설명을 읽어보세요.

    function turnOnOffClass() {
      var dfd  = $.Deferred();
      var $wp1 = $('.sub_txt_wp01');
      var $wp2 = $('.sub_txt_wp02');
      setTimeout(function() { $wp1.find('.a').addClass('on'); }, 1000); 
      setTimeout(function() { $wp1.find('.b').addClass('on'); }, 2000); 
      setTimeout(function() { $wp1.find('.ab_wp').removeClass('on'); }, 3000);
      setTimeout(function() { $wp2.find('.c').addClass('on'); }, 4000); 
      setTimeout(function() { $wp2.find('.d').addClass('on'); }, 5000); 
      setTimeout(function() { $wp2.find('.cd_wp').removeClass('on'); }, 6000);
      setTimeout(function() { dfd.resolve($($wp1, $wp2)); }, 7000);
      return dfd.promise();
    }
    
    function resetClass($wps){
      var $wp1 = $wps.eq(0);
      var $wp2 = $wps.eq(1);
      $wp1.find('.a, .b').removeClass('on');
      $wp1.find('.ab_wp').addClass('on');
      $wp2.find('.c, .d').removeClass('on');
      $wp2.find('.cd_wp').addClass('on');
      loopAction();
    }
    
    function loopAction(){
      $.when(turnOnOffClass()).then(resetClass);
    }
    
    loopAction();
    

    자! 그럼 결과를 도출하기 위한 코드 작성 과정을 찬찬히 살펴봅시다.

    참고로 질문 코드에 jQuery 라이브러리를 사용한 것을 확인하고, jQuery를 사용한 답변을 드렸습니다. 만약 JavaScript 코드 질문 이었다면 Promise 객체를 사용한 방법으로 답변 했을 것입니다.

    먼저 작성할 함수에 대해 알아봅시다.

    반복 수행을 위해서는 크게 3가지 일로 구분 지을 수 있습니다.

    1. reset: 변경 전 상태로 돌릴 수 있어야 하고,
    2. turnOnOff: 변경하는 과정을 수행해야 하고
    3. loop: 이를 활용하여 반복 처리해야 합니다.

    제작할 함수 이름을 다음과 같이 설정합니다.

    // on 클래스를 추가, 제거하는 함수
    function turnOnOffClass() { ... }
    
    // 클래스 설정을 초기화 하는 함수
    function resetClass() { ... }
    
    // 일련의 행동을 반복하는 함수
    function loopAction() { ... }
    

    제작한 함수 중 loopAction() 코드를 살펴보면 내부에 $.when(), .then() 등이 사용 되었습니다. 질문이 요구하는 바대로 일련의 동작이 모두 끝난 때까지 동작을 지연시켜야 하기 때문입니다.

    jQuery API를 살펴보면 지연(Deferred)된 동작을 처리하기 위한 방법으로 $.when(), deferred.then() 등을 제공합니다. 아래 레퍼런스를 통해 사용 방법을 확인할 수 있습니다.

    이를 활용하여 작성된 코드는 다음과 같습니다. 코드를 해석하면 turnOnOffClass() 함수가 완료되면(when), resetClass() 함수를 실행합니다. 여기서 중요한 포인트는 resetClass() 함수가 실행되는 시점을 지연(deferred) 시켰다는 점입니다.

    function loopAction(){
      // turnOnOffClass() 함수가 실행되는 동안
      // 함수 내부에 정의된 시간(7초)에 따른 모든 동작이 종료되면,
      $.when(turnOnOffClass())
      // resetClass 함수를 실행합니다.
       .then(resetClass);
    }
    
    // 반복 수행할 동작이 정의된 함수 loopAction()를 실행시킵니다. (1회 수행)
    loopAction();
    

    이어서 turnOnOffClass() 함수 코드를 살펴봅시다. 질문 코드에 없는 내용만 다뤄보겠습니다. $.Deferred() 코드를 눈여겨 봐주세요. 앞서 지연(Deferred)된 처리가 필요하다고 이야기 했었죠. jQuery는 지연된 처리를 위한 방법을 제공하고 있어 활용한 것입니다.

    dfd 변수에 참조된 Deferred 객체는 resolve() 메소드와 reject() 메서드 등을 가지는데 이 예제는 비동기 통신(Ajax)을 다루는 것이 아니므로 resolve() 메서드 만 사용합니다.

    dfd.resolve() 실행 시, deferred.then() 메서드에 전달할 인자를 설정할 수 있습니다. $($wp1, $wp2) 코드를 통해 $wp1, $wp2를 수집한 jQuery 객체를 전달합니다.

    마지막으로 함수의 결과 값으로 deferred.promise() 객체를 반환합니다. 프로미스 객체를 반환해야 $.when() 메서드에서 이를 받아 .then() 메서드를 실행할 수 있습니다. 자세한 사용법은 jQuery API deferred.promise()을 참고하세요.

    /**
     * @description 'on' 클래스 속성을 추가/제거하는 일련의 동작을 정의합니다.
     * @returns {object} jQuery.Deferred().promise() 객체를 반환.
     */
    function turnOnOffClass() {
    
      // Deferred : "실행(행동) 등을 연기(지연)한다는 의미"입니다.
      // jQuery.Deferred() 객체를 생성한 후, dfd 변수에 참조합니다.
      var dfd = $.Deferred();
    
      // 문서 객체를 찾아 jQuery 객체를 생성한 후, 각 변수에 참조합니다.
      var $wp1 = $('.sub_txt_wp01');
      var $wp2 = $('.sub_txt_wp02');
    
      // 1초 마다 처리할 일을 각각 설정합니다.
      setTimeout(function() {
        $wp1.find('.a').addClass('on'); }, 1000); 
      setTimeout(function() { 
        $wp1.find('.b').addClass('on'); }, 2000); 
      setTimeout(function() { 
        $wp1.find('.ab_wp').removeClass('on'); }, 3000);
      setTimeout(function() { 
        $wp2.find('.c').addClass('on'); }, 4000); 
      setTimeout(function() { 
        $wp2.find('.d').addClass('on'); }, 5000); 
      setTimeout(function() { 
        $wp2.find('.cd_wp').removeClass('on'); }, 6000);
    
      // 마지막 수행에서 지연 객체를 참조하는 dfd 변수를 통해
      // 객체의 결정 메서드인 resolve()를 실행하면서 제어할
      // jQuery 객체들($wp1, $wp2)을 추가한 jQuery 객체를
      // 생성하여 전달합니다.
      setTimeout(function() { 
        dfd.resolve($($wp1, $wp2)); }, 7000);
    
      // dfd 객체 메서드 promise()를 실행해 promise 객체를 반환합니다.
      return dfd.promise();
    
    }
    

    다음은 수행되기 전으로 되돌릴 resetClass() 함수를 살펴봅시다. resetClass() 함수는 .then() 함수에 전달되어 대기하다 $.when() 이후 .then() 구문에서 실행됩니다.

    dfd.resolve() 실행 시 전달한 jQuery 객체는 첫번째 인자로 전달됩니다. 적당한 매개변수 이름 $wps 을 설정합니다. (API에는 target으로 사용됨)

    나머지는 최초 상태로 돌리는 코드를 작성합니다.

    /**
     * @description class 속성을 초기 설정으로 되돌립니다.
     * @param {jQuery Object} $wps 프로미스(promise)로부터 전달된 jQuery 객체입를 매개변수로 받습니다.
     */
    function resetClass($wps){
      // 전달 받은 jQuery 객체(수집된 .sub_txt_wp01, .sub_txt_wp02 문서 객체)에서
      // 0, 1 로 인덱싱된 jQuery 객체를 각각 필터링하여 지역 변수 $wp1, $wp2에 참조합니다.
      var $wp1 = $wps.eq(0);
      var $wp2 = $wps.eq(1);
    
      // 초기 설정대로 class 속성을 되돌립니다.
      $wp1.find('.a, .b').removeClass('on');
      $wp1.find('.ab_wp').addClass('on');
      $wp2.find('.c, .d').removeClass('on');
      $wp2.find('.cd_wp').addClass('on');
    
      // 반복해야 될 동작을 다시 실행시킵니다.
      // (2, 3, 4, ..... 반복 수행)
      loopAction();
    }
    

    자! 이제 마무리입니다. 앞서 다룬 코드를 종합(주석 포함)해봅시다.

    /**
     * @description 'on' 클래스 속성을 추가/제거하는 일련의 동작을 정의합니다.
     * @returns {object} jQuery.Deferred().promise() 객체를 반환.
     */
    function turnOnOffClass() {
    
      // Deferred : "실행(행동) 등을 연기(지연)한다는 의미"입니다.
      // jQuery.Deferred() 객체를 생성한 후, dfd 변수에 참조합니다.
      var dfd = $.Deferred();
    
      // 문서 객체를 찾아 jQuery 객체를 생성한 후, 각 변수에 참조합니다.
      var $wp1 = $('.sub_txt_wp01');
      var $wp2 = $('.sub_txt_wp02');
    
      // 1초 마다 처리할 일을 각각 설정합니다.
      setTimeout(function() {
        $wp1.find('.a').addClass('on'); }, 1000); 
      setTimeout(function() { 
        $wp1.find('.b').addClass('on'); }, 2000); 
      setTimeout(function() { 
        $wp1.find('.ab_wp').removeClass('on'); }, 3000);
      setTimeout(function() { 
        $wp2.find('.c').addClass('on'); }, 4000); 
      setTimeout(function() { 
        $wp2.find('.d').addClass('on'); }, 5000); 
      setTimeout(function() { 
        $wp2.find('.cd_wp').removeClass('on'); }, 6000);
    
      // 마지막 수행에서 지연 객체를 참조하는 dfd 변수를 통해
      // 객체의 결정 메서드인 resolve()를 실행하면서 제어할
      // jQuery 객체들($wp1, $wp2)을 추가한 jQuery 객체를
      // 생성하여 전달합니다.
      setTimeout(function() { 
        dfd.resolve($($wp1, $wp2)); }, 7000);
    
      // dfd 객체 메서드 promise()를 실행해 promise 객체를 반환합니다.
      return dfd.promise();
    
    }
    
    /**
     * @description class 속성을 초기 설정으로 되돌립니다.
     * @param {jQuery Object} $wps 프로미스(promise)로부터 전달된 jQuery 객체입를 매개변수로 받습니다.
     */
    function resetClass($wps){
      // 전달 받은 jQuery 객체(수집된 .sub_txt_wp01, .sub_txt_wp02 문서 객체)에서
      // 0, 1 로 인덱싱된 jQuery 객체를 각각 필터링하여 지역 변수 $wp1, $wp2에 참조합니다.
      var $wp1 = $wps.eq(0);
      var $wp2 = $wps.eq(1);
    
      // 초기 설정대로 class 속성을 되돌립니다.
      $wp1.find('.a, .b').removeClass('on');
      $wp1.find('.ab_wp').addClass('on');
      $wp2.find('.c, .d').removeClass('on');
      $wp2.find('.cd_wp').addClass('on');
    
      // 반복해야 될 동작을 다시 실행시킵니다.
      // (2, 3, 4, ..... 반복 수행)
      loopAction();
    }
    
    /**
     * @description 반복 수행될 동작을 정의합니다.
     */
    function loopAction(){
      // turnOnOffClass() 함수가 실행되는 동안
      // 함수 내부에 정의된 시간(7초)에 따른 모든 동작이 종료되면,
      $.when(turnOnOffClass())
      // resetClass 함수를 실행합니다.
       .then(resetClass);
    }
    
    // 반복 수행할 동작이 정의된 함수 loopAction()를 실행시킵니다. (1회 수행)
    loopAction();
    

    완성 코드

    최종적으로 주석을 제거한 코드는 다음과 같습니다. :-)

    function turnOnOffClass() {
      var dfd  = $.Deferred();
      var $wp1 = $('.sub_txt_wp01');
      var $wp2 = $('.sub_txt_wp02');
      setTimeout(function() { $wp1.find('.a').addClass('on'); }, 1000); 
      setTimeout(function() { $wp1.find('.b').addClass('on'); }, 2000); 
      setTimeout(function() { $wp1.find('.ab_wp').removeClass('on'); }, 3000);
      setTimeout(function() { $wp2.find('.c').addClass('on'); }, 4000); 
      setTimeout(function() { $wp2.find('.d').addClass('on'); }, 5000); 
      setTimeout(function() { $wp2.find('.cd_wp').removeClass('on'); }, 6000);
      setTimeout(function() { dfd.resolve($($wp1, $wp2)); }, 7000);
      return dfd.promise();
    }
    
    function resetClass($wps){
      var $wp1 = $wps.eq(0);
      var $wp2 = $wps.eq(1);
      $wp1.find('.a, .b').removeClass('on');
      $wp1.find('.ab_wp').addClass('on');
      $wp2.find('.c, .d').removeClass('on');
      $wp2.find('.cd_wp').addClass('on');
      loopAction();
    }
    
    function loopAction(){
      $.when(turnOnOffClass()).then(resetClass);
    }
    
    loopAction();
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
  • var addClassFlag = false;
    
    setInterval(
    if( addClassFlag ){
        addClass();
    }, 7000); 
    
    functoin addClass(){
        setTimeout(function() { $('.sub_txt_wp01').find('.a').addClass('on'); }, 1000); 
        setTimeout(function() { $('.sub_txt_wp01').find('.b').addClass('on'); }, 2000); 
        setTimeout(function() { $('.sub_txt_wp01').find('.ab_wp').removeClass('on'); }, 3000);
        setTimeout(function() { $('.sub_txt_wp02').find('.c').addClass('on'); }, 4000); 
        setTimeout(function() { $('.sub_txt_wp02').find('.d').addClass('on'); }, 5000); 
        setTimeout(function() { $('.sub_txt_wp02').find('.cd_wp').removeClass('on'); }, 6000);
    };
    

    에디터로 작성해서 틀릴지도 모르겠는데 이렇게하면 어떨까요?

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)