изменить значение переменной в каждой () последней итерации функции - jQuery

Вот моя скрипка ссылка.

Так что у меня будет несколько шагов, которые нужно анимировать один за другим. И чтобы сделать их анимированными один за другим, я использовал некоторую переменную flag. В зависимости от его значения соответствующий шаг должен быть анимирован.

Но есть одна проблема - его значение не меняется на первом шаге, и поэтому, когда вы нажимаете на 2 (на временной шкале), анимируется только первый шаг. Проблема заключается в приведенной ниже части, когда я анимирую каждую стрелку одну за другой в функции each(), а значение переменной flag изменяется в последней итерации стрелок:

var flag = 0;
function step_1(){
    jQuery(".step_1_nav").addClass('active_bullet_point');
    jQuery(".step_1 .label").addClass('active_label_text');

    var delay = 0;
    jQuery('.step_1 .arrows span').each(function(index) {
        var $this = $(this);
        var total = $('.step_1 .arrows span').length;
        $this.delay(delay).animate({opacity:1}, 100, function(){
            $this.addClass('white_animated_arrow');
            if (index === (total - 1)) {
                jQuery(".step_1 .bullet_point").addClass('active_bullet_point');
                flag = 1;
            }
        });
        delay += 100;
    });
}

jQuery(".step_2_nav").click(function(){
    step_1();
    console.log(flag); /* here flag returns 0 instead of 1 */
    step_2();
});

Когда я помещаю эту часть

if (index === (total - 1)) {
    jQuery(".step_1 .bullet_point").addClass('active_bullet_point');
    flag = 1;
}

out of animate значение флага функции обратного вызова изменяется на 1, но это происходит немедленно, не дожидаясь последней итерации стрелки, и все 2 шага анимируются немедленно.

Что мне здесь не хватает? Любые идеи, пожалуйста?


person aiddev    schedule 30.06.2017    source источник
comment
$this.delay(delay).animate({opacity:1}, 100, function(){ /* это функция обратного вызова */ } }), функция обратного вызова выполняется после step_2() вызов функции. Из-за этого значение флага остается равным 0.   -  person Rohit Chahar    schedule 30.06.2017
comment
@aidadev - пожалуйста, проверьте мой ответ   -  person Satinder singh    schedule 30.06.2017


Ответы (5)


Я делаю это с помощью setInterval()

JS FIDDLE DEMO

var counter_step1 = 0;
var counter_step2 = 0;
var step1Completed = false;
var timeDelay = 400; // set delay time accordingly

function step1() {

  $(".step_1 .label").addClass("active_label_text");
  var arrowCount = $(".arrows_down span").size();
  var myFisrt = setInterval(function() {
    if (counter_step1 < arrowCount) {
      counter_step1++
      $(".arrows_down span:nth-child(" + counter_step1 + ")").addClass("white_animated_arrow");
    } else {
      $(".step_1 .bullet_point").addClass("active_bullet_point");
      step1Completed = true;
      clearInterval(myFisrt);
    }
  }, timeDelay);
}


function step2() {
  var arrowCount = $(".arrows_up span").size();
  var mySecond = setInterval(function() {
    if (step1Completed) {
      $(".step_2 .label").addClass("active_label_text");
      if (arrowCount > counter_step2) {
        $(".arrows_up span:nth-child(" + arrowCount + ")").addClass("white_animated_arrow");
        arrowCount--
      } else {
        $(".step_2 .bullet_point").addClass("active_bullet_point");
        clearInterval(mySecond);
      }
    }
  }, timeDelay);
}

function setAnimation(myVALUE) {
  step1();
  if (myVALUE == "STEP2") { step2();  }
}

$(".step_1_nav").on('click', function() {
  setAnimation("STEP1");
});

$(".step_2_nav").on('click', function() {
  setAnimation("STEP2");
});
person Satinder singh    schedule 30.06.2017

Не уверен, что хорошо понял. Чего вы хотите, когда шаг 2 состоит в том, чтобы анимация выполнялась в обратном порядке, верно?

Вы можете добиться этого, используя jQuery reverse(), например:

jQuery(jQuery('.step_2 .arrows span').get().reverse()).each();

var flag = 0;
function step_1(){    
    jQuery(".step_1_nav").addClass('active_bullet_point');
    jQuery(".step_1 .label").addClass('active_label_text');

    var delay = 0;
    jQuery('.step_1 .arrows span').each(function(index) {
        var $this = $(this);
        var total = $('.step_1 .arrows span').length;
        $this.delay(delay).animate({opacity:1}, 100, function(){
            $this.addClass('white_animated_arrow');
            if (index === (total - 1)) {
                jQuery(".step_1 .bullet_point").addClass('active_bullet_point');
                flag = 1;
            }
        });
        delay += 100;
    });
}

function step_2(){
    if(flag == 1){
        jQuery(".step_2_nav").addClass('active_bullet_point');
        jQuery(".step_2 .label").addClass('active_label_text');

        var delay = 0;
        jQuery('.step_2 .arrows span').each(function(index) {
            var $this = $(this);
            var total = $('.step_2 .arrows span').length;
            $this.delay(delay).animate({opacity:1}, 100, function(){
                $this.addClass('white_animated_arrow');
                if (index === (total - 1)) {
                    jQuery(".step_2 .bullet_point").addClass('active_bullet_point');
                    flag = 1;
                }
            });
            delay += 100;
        });
    }
}

jQuery(".step_1_nav").click(function(){
    step_1();
});

jQuery(".step_2_nav").click(function(){
    step_1();
    flag = 1;
    console.log(flag);
    step_2();
});
.step {
  margin-right:30px;
  display:inline-block;
  vertical-align:top;
  text-align:center;
  margin-top:20px;
  margin-left:20px;
}
.arrows {
  width:10px;
  display:inline-block;
  vertical-align:top;
}
.arrows_up {
}
.arrows span {
    border: solid #000;
    border-width: 0 2px 2px 0;
    display: block;
    padding: 4px;
    margin-bottom: 4px;
    width: 0;
    height: 0;
    -webkit-transition: border-color 0.4s;
    -moz-transition: border-color 0.4s;
    transition: border-color 0.4s;
}
.arrows_down span {
    transform: rotate(135deg);
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
}
.arrows_up span {
    transform: rotate(-135deg);
    -webkit-transform: rotate(-135deg);
    -moz-transform: rotate(-135deg);
    -ms-transform: rotate(-135deg);
}
.label {
  color:#000;
  margin-bottom:10px;
  font-weight:bold;
  display:block;
  font-family:'Arial';
}
.bullet_point span {
    font-family:'Arial';
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #000;
    display: inline-block;
    vertical-align: middle;
    -webkit-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}
.step_2 .bullet_point {
  margin-bottom:15px;
}
.step_2 .label {
  margin-top:5px;
}
.active_label_text {
  color:red;
}
span.white_animated_arrow {
    border-color: red;
}
.timer_nav {
  margin-top:20px;
  margin-left:0px;
}
.timer_nav  span.timeline {
  color:#000 !important;
  cursor:text;
}
.timer_nav span {
  color:#000;
  font-size:20px;
  cursor:pointer;
  font-family:'Arial';
  font-weight:bold;
  margin:0px 10px;
  -webkit-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}
.timer_nav span:hover {
  color:red;
}
.active_bullet_point {
  color:red;
}
.timer_nav span.active_bullet_point {
  color:red;
}
.active_bullet_point span {
  background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="step step_1">
  <span class="label">STEP 1</span>
  <div class="arrows arrows_down">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>
  <div class="bullet_point"><span></span></div>
</div>

<div class="step step_2">
  <div class="bullet_point"><span></span></div> 
  <div class="arrows arrows_up">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>
  <span class="label">STEP 2</span>
</div>

<div class="timer_nav">
  <span class="timeline">Timeline</span>
  <span class="step_1_nav">1</span>
  <span class="step_2_nav">2</span>
</div>

person JV Lobo    schedule 30.06.2017
comment
Нет, я знаю об обратном функционале. Я просто хочу, когда первая точка маркера становится красной, только в этом случае должна начинаться вторая анимация. Теперь, когда вы нажмете на 2 на временной шкале, вы увидите, что только элементы первого шага становятся красными, но элементы второго шага становятся красными, только если вы дважды щелкните на 2, поскольку значение флага изменяется только при двойном щелчке по нему @JV Lobo - person aiddev; 30.06.2017
comment
Я понимаю. Я отредактировал свой ответ. Вы можете установить флаг в начале функции шага 1 и вызвать функцию шага 2 прямо там, верно? - person JV Lobo; 30.06.2017
comment
Нет, шаг_2 должен происходить только после завершения шага_1, чтобы анимация выглядела логично. @СП Лобо - person aiddev; 30.06.2017
comment
Думаю, теперь я понял. Я снова отредактировал. Поэтому я добавил только flag = 1; вызов step_1(); когда вы нажимаете на кнопку шага 2. это то поведение, которое вы ищете, верно? - person JV Lobo; 30.06.2017
comment
Нет, вот так оба шага начинают анимироваться вместе. Моя проблема заключается в том, чтобы понять, почему значение флага не изменяется в последней итерации каждой() функции @JV Lobo - person aiddev; 30.06.2017
comment
значение флага изменяется на последней итерации, но когда вы нажимаете кнопку шага 2, вы одновременно запускаете функцию шага_1 и функцию шага_2, а шаг_1 занимает 100 миллисекунд на каждый элемент, поэтому, когда шаг_2 запускается, шаг_1 еще не завершен , поэтому значение флага еще не изменилось. ты понимаешь? - person JV Lobo; 30.06.2017

Это похоже на анимацию рассинхронизации, вы можете просто вызвать свой step2 после завершения step1, то есть поместить его в свою функцию обратного вызова на шаге 1.
Я установил setTimeout, потому что кажется, что у вас есть дополнительный переход, это сделает ваш вызов шага 1 еще длиннее.

    function step_1(child) {
        jQuery(".step_1_nav").addClass('active_bullet_point');
        jQuery(".step_1 .label").addClass('active_label_text');

        var delay = 0;
        jQuery('.step_1 .arrows span').each(function(index) {
            var $this = $(this);
            var total = $('.step_1 .arrows span').length;
            $this.animate({
                opacity: 1
            }, delay, function() {
                $this.addClass('white_animated_arrow');
                if (index === (total - 1)) {
                    jQuery(".step_1 .bullet_point").addClass('active_bullet_point');
                    if(child) setTimeout(()=> step_2(), 300);
                }
            });
            delay += 100;
        });
    }

    function step_2() {
        // if (flag == 1) {
            jQuery(".step_2_nav").addClass('active_bullet_point');
            jQuery(".step_2 .label").addClass('active_label_text');

            var delay = 0;
            jQuery('.step_2 .arrows span').each(function(index) {
                var $this = $(this);
                var total = $('.step_2 .arrows span').length;
                $this.delay(delay).animate({
                    opacity: 1
                }, 100, function() {
                    $this.addClass('white_animated_arrow');
                    if (index === (total - 1)) {
                        jQuery(".step_2 .bullet_point").addClass('active_bullet_point');
                    }
                });
                delay += 100;
            });
        // }
    }

    jQuery(".step_1_nav").click(function() {
        step_1();
    });

    jQuery(".step_2_nav").click(function() {
        step_1(true);
    });
.step {
        margin-right: 30px;
        display: inline-block;
        vertical-align: top;
        text-align: center;
        margin-top: 20px;
        margin-left: 20px;
    }
    
    .arrows {
        width: 10px;
        display: inline-block;
        vertical-align: top;
    }
    
    .arrows_up {}
    
    .arrows span {
        border: solid #000;
        border-width: 0 2px 2px 0;
        display: block;
        padding: 4px;
        margin-bottom: 4px;
        width: 0;
        height: 0;
        -webkit-transition: border-color 0.4s;
        -moz-transition: border-color 0.4s;
        transition: border-color 0.4s;
    }
    
    .arrows_down span {
        transform: rotate(135deg);
        -webkit-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
    }
    
    .arrows_up span {
        transform: rotate(-135deg);
        -webkit-transform: rotate(-135deg);
        -moz-transform: rotate(-135deg);
        -ms-transform: rotate(-135deg);
    }
    
    .label {
        color: #000;
        margin-bottom: 10px;
        font-weight: bold;
        display: block;
        font-family: 'Arial';
    }
    
    .bullet_point span {
        font-family: 'Arial';
        width: 12px;
        height: 12px;
        border-radius: 50%;
        background: #000;
        display: inline-block;
        vertical-align: middle;
        -webkit-transition: all 0.4s;
        -moz-transition: all 0.4s;
        transition: all 0.4s;
    }
    
    .step_2 .bullet_point {
        margin-bottom: 15px;
    }
    
    .step_2 .label {
        margin-top: 5px;
    }
    
    .active_label_text {
        color: red;
    }
    
    span.white_animated_arrow {
        border-color: red;
    }
    
    .timer_nav {
        margin-top: 20px;
        margin-left: 0px;
    }
    
    .timer_nav span.timeline {
        color: #000 !important;
        cursor: text;
    }
    
    .timer_nav span {
        color: #000;
        font-size: 20px;
        cursor: pointer;
        font-family: 'Arial';
        font-weight: bold;
        margin: 0px 10px;
        -webkit-transition: all 0.4s;
        -moz-transition: all 0.4s;
        transition: all 0.4s;
    }
    
    .timer_nav span:hover {
        color: red;
    }
    
    .active_bullet_point {
        color: red;
    }
    
    .timer_nav span.active_bullet_point {
        color: red;
    }
    
    .active_bullet_point span {
        background: red;
    }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="step step_1">
        <span class="label">STEP 1</span>
        <div class="arrows arrows_down">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
        <div class="bullet_point"><span></span></div>
    </div>
    <div class="step step_2">
        <div class="bullet_point"><span></span></div>
        <div class="arrows arrows_up">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
        <span class="label">STEP 2</span>
    </div>
    <div class="timer_nav">
        <span class="timeline">Timeline</span>
        <span class="step_1_nav">1</span>
        <span class="step_2_nav">2</span>
    </div>
    </div>

person Horken    schedule 30.06.2017

Я сделал ниже, что это будет работать, но это не правильный метод для решения проблемы.

Это происходит потому, что JS не останавливается, пока не закончится step_1(). Он не ожидает цикла «задержка» в step_1() и не вызывает step_2(). Если вы поместите alert() в обе функции, вы узнаете.

jQuery(".step_2_nav").click(function(){`enter code here`
      step_1();
      flag=1;
      step_2();
})

Вы также можете попробовать использовать https://api.jquery.com/category/deferred-object/

Надеюсь так поможет

person Sameer    schedule 30.06.2017

Укажите анонимный обратный вызов и сделайте так, чтобы step_1 принял его:

function step_1(callback){
    if(!callback) callback =function(){};
    jQuery(".step_1_nav").addClass('active_bullet_point');
    jQuery(".step_1 .label").addClass('active_label_text');

    var delay = 0;
    jQuery('.step_1 .arrows span').each(function(index) {
        var $this = $(this);
        var total = $('.step_1 .arrows span').length;
        $this.delay(delay).animate({opacity:1}, 100, function(){
            $this.addClass('white_animated_arrow');
            if (index === (total - 1)) {
                jQuery(".step_1 .bullet_point").addClass('active_bullet_point');
                callback();
            }
        });
        delay += 100;
    });
}

И назовите это:

jQuery(".step_2_nav").click(function(){
    step_1(step_2);
});

Это скрипка

person tiepnv    schedule 30.06.2017