【问题标题】:change variable value in each() function last iteration - jQuery在 each() 函数最后一次迭代中更改变量值 - jQuery
【发布时间】:2017-12-04 01:05:50
【问题描述】:

这是我的小提琴link

所以我将有多个步骤,应该一个一个地动画。为了让它们一一动画化,我使用了一些 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 个步骤都会立即进行动画处理。

我在这里缺少什么?请问有什么想法吗?

【问题讨论】:

  • $this.delay(delay).animate({opacity:1}, 100, function(){ /* 这是一个回调函数 */ } }),回调函数在 step_2() 函数调用之后执行。因此,标志值保持为 0。
  • @aidadev - 请检查我的答案

标签: javascript jquery animation each


【解决方案1】:

我使用 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");
});

【讨论】:

    【解决方案2】:

    不确定我是否理解得很好。当第 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>

    【讨论】:

    • 不,我知道反向功能。我只想在第一个项目符号变为红色时,只有在这种情况下才应该开始第二个动画。现在,当您从时间轴单击“2”时,您将看到只有第一步的东西变成红色,但只有当您双击“2”时第二步的东西才会变成红色,因为只有当您双击它时才会更改标志值@合资路宝
    • 我明白了。我已经编辑了我的答案。您可以在第 1 步函数的开头设置标志并在此处调用第 2 步函数,对吗?
    • 不,step_2 应该只在 step_1 完成时发生,这样动画才会看起来合乎逻辑。 @JV Lobo
    • 我想我现在明白了。我又编辑了。所以我只添加了 flag = 1;调用 step_1();当您单击第 2 步按钮时。这就是您要寻找的行为,对吗?
    • 不,像这样两个步骤一起开始动画。我的问题是理解为什么在 each() 函数的最后一次迭代@JV Lobo 中没有更改标志值
    【解决方案3】:

    这有点像不同步动画,你可以在step1完成后调用你的step2,意思是把它放在你的回调函数中。
    我设置了setTimeout,因为您似乎有额外的过渡,这会使您的 step1 调用时间更长。

        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>

    【讨论】:

      【解决方案4】:

      我已经做了以下事情,这将起作用,但不是解决解决方案的正确方法。

      这是因为 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/

      希望对你有帮助

      【讨论】:

        【解决方案5】:

        指定一个匿名回调,并让 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);
        });
        

        这是fiddle

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-01
          • 1970-01-01
          • 2011-04-09
          • 2012-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多