【问题标题】:change color of items one by one一项一项更改项目的颜色
【发布时间】:2015-10-06 19:55:14
【问题描述】:

我编写了一个脚本,它创建了一组排列成一个圆圈的小圆圈,这些圆圈通过一个循环一个一个地添加到 DOM 中。在第一个循环完成后(所以我希望这是i == 54)我想开始另一个循环,从列表中的第一个圆圈开始,并一个一个地将圆圈的颜色从灰色变为红色。

这是我的代码:

var i = 1;
var appendCircle = function loop() {

  setTimeout(function() {
    var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
    var $container = $(".circles-wrapper .circles");
    $container.append($circle);
    i++;

    if (i < 55) {
      loop();
    }
  }, 20);

  // this is the problem because this change color of all small circles at once.

  if (i == 54) {
    setTimeout(function() {

      $(".circle").each(function() {
        $(this).css({
          "background": "blue"
        });
      })
    }, 20);
  }
};

setTimeout(appendCircle, 100);
.circles-wrapper {
  position: absolute;
  top: 39%;
  left: 51%;
}
.circles {
  position: relative;
  transform: rotateY(48deg);
}
.circle {
  width: .2em;
  height: .2em;
  margin: -.2em;
  border-radius: 50%;
  background: #ceced0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circles-wrapper">
  <div class="circles"></div>
</div>

【问题讨论】:

    标签: javascript jquery css loops


    【解决方案1】:

    您为每个圆指定了“circle”+index 类,因此您所要做的就是遍历每个索引并更改每个元素的背景颜色。我所做的是使用相同的循环函数,当我达到 55 后,我取了它的 mod 55 并用它来选择圆圈。代码和sn-p如下。

    我还注意到一些圆圈重叠。如果您生成 50 个圆圈,则不会有任何重叠。我写了下面的代码来反映这一点。

    var i = 1;
    var appendCircle = function loop() {
      setTimeout(function() {
        if (i < 51) {
    		var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
    		var $container = $(".circles-wrapper .circles");
    		$container.append($circle);
        }
    	else{
    		var circleIndex = (i % 51)+1;
    		$(".circle"+circleIndex).css("background-color", "blue");
    	}
    	
    	if(i<109){
    		loop();
    	}
    	i++;
      }, 20);
    };
    
    setTimeout(appendCircle, 100);
    .circles-wrapper {
      position: absolute;
      top: 39%;
      left: 51%;
    }
    .circles {
      position: relative;
      transform: rotateY(48deg);
    }
    .circle {
      width: .2em;
      height: .2em;
      margin: -.2em;
      border-radius: 50%;
      background: #ceced0;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="circles-wrapper">
      <div class="circles"></div>
    </div>

    【讨论】:

    • 非常感谢您的回答也感谢修复重叠问题
    【解决方案2】:

    在您第一次通过后,您可能希望找到创建的圈子并对其进行修改。您正在为他们提供circle + i 的类,以便您可以轻松找到它们。检查代码片段。我添加了第三遍只是因为。

    var i = 1,
      CIRCLE_COUNT = 52;
    var appendCircle = function loop() {
    
      setTimeout(function() {
        i++;
    
        // first pass
        if (i < CIRCLE_COUNT * 1) {
    
          var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
          var $container = $(".circles-wrapper .circles");
          $container.append($circle);
        } 
        // second pass
        else if (i < CIRCLE_COUNT * 2) {
          $(".circle" + (i % CIRCLE_COUNT+1)).css('background', 'blue');
        }
        
        // third pass
        else if (i < CIRCLE_COUNT * 3) {
          $(".circle" + (i % CIRCLE_COUNT+1)).remove();
        }
        
        // keep looping?
        if (i <= CIRCLE_COUNT * 3)
          loop();
    
      }, 20);
    
    
    };
    
    setTimeout(appendCircle, 100);
    .circles-wrapper {
      position: absolute;
      top: 39%;
      left: 51%;
    }
    .circles {
      position: relative;
      transform: rotateY(48deg);
    }
    .circle {
      width: .2em;
      height: .2em;
      margin: -.2em;
      border-radius: 50%;
      background: #ceced0;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="circles-wrapper">
      <div class="circles"></div>
    </div>

    【讨论】:

      【解决方案3】:

      像这样?我在您的.each() 中放置了一个超时功能,以便在您将圆圈颜色更改为蓝色时在循环的每次迭代之间产生延迟

      var i = 1;
      var appendCircle = function loop() {
      
        setTimeout(function() {
          var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
          var $container = $(".circles-wrapper .circles");
          $container.append($circle);
          i++;
      
          if (i < 55) {
            loop();
          }
        }, 20);
      
        // this is the problem because this change color of all small circles at once.
      
        if (i == 54) {
          var time = 50;
          $(".circle").each(function() {
            var $this = $(this)
            setTimeout(function(){
              $this.css({
                "background": "blue"
              }); 
            }, time)
            time += 50;
      
          });
        }
      };
      
      setTimeout(appendCircle, 100);
      .circles-wrapper {
        position: absolute;
        top: 39%;
        left: 51%;
      }
      .circles {
        position: relative;
        transform: rotateY(48deg);
      }
      .circle {
        width: .2em;
        height: .2em;
        margin: -.2em;
        border-radius: 50%;
        background: #ceced0;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div class="circles-wrapper">
        <div class="circles"></div>
      </div>

      【讨论】:

        【解决方案4】:

        您只需要更改一个元素的 CSS,然后启动超时以更改下一个。

        var i = 1;
        var appendCircle = function loop() {
        
          setTimeout(function() {
            var $circle = "<div class='circle circle" + i + "' style='transform:rotate(" + 7.2 * i + "deg) translate(3em)'></div>";
            var $container = $(".circles-wrapper .circles");
            $container.append($circle);
            i++;
        
            if (i < 55) {
              loop();
            }
          }, 20);
        
          var j = 0;
        
          function changeColor() {
            $(".circle").eq(j).css("background", "blue");
            j++;
            if (j >= $(".circle").length) {
              clearInterval(changeInterval);
            }
          }
          if (i == 53) {
            setInterval(changeColor, 20);
          }
        
        }
        setTimeout(appendCircle, 100);
        .circles-wrapper {
          position: absolute;
          top: 39%;
          left: 51%;
        }
        .circles {
          position: relative;
          transform: rotateY(48deg);
        }
        .circle {
          width: .2em;
          height: .2em;
          margin: -.2em;
          border-radius: 50%;
          background: #ceced0;
        }
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div class="circles-wrapper">
          <div class="circles"></div>
        </div>

        【讨论】:

          【解决方案5】:

          jQuery 的一些特性可以让这样的动画变得相当简单,尽管您需要了解几种方法。

          jQuery 的 .delay().promise().then() 和 javascript 的 Array.prototype.reduce() 可以被如下利用:

          var appendCircles = function($container) {
              //create and append hidden circles
              for(var i=0; i<50; i++) {
                  $("<div class='circle'></div>").css('transform', 'rotate(' + 7.2 * i + 'deg) translate(3em)').hide().appendTo($container);
              }
          
              //find the freshly appended hidden circles
              var $circles = $container.find(".circle");
          
              //initial delay
              $circles.eq(0).delay(100).promise()
              .then(function() {
                  //show the circles, one by one
                  return $circles.get().reduce(function(promise, el) {
                      return promise.then(function() {
                          return $(el).show().delay(20).promise();
                      });
                  }, $.when());//$when() is a resolved promise that gets the built promise chain started
              })
              .then(function() {
                  //make circles blue, one by one
                  return $circles.get().reduce(function(promise, el) {
                      return promise.then(function() {
                          return $(el).css('backgroundColor', 'blue').delay(20).promise();
                      });
                  }, $.when());//$when() is a resolved promise that gets the built promise chain started
              });
          };
          
          appendCircles($(".circles"));
          

          codepen

          .reduce() 可能需要一些解释。 $circles.get() 返回一个数组,.reduce(...) 用于构建等效于initialPromise.then(...).then(...).then(...) 的承诺链。此技巧按顺序执行两次,以给出初始的“显示”效果,然后是颜色变化效果。

          如果你想用 jQuery 制作自定义动画序列,这套方法值得学习。

          【讨论】:

            猜你喜欢
            • 2012-07-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多