JS / jQuery - 按顺序动画div

时间:2016-01-28 20:52:52

标签: javascript jquery css

我正在构建一个简单的Simon Says / Memory应用程序,我正在尝试使用jQuery来动画一些用户重复模式的div。我被困住的部分是按顺序点亮div。

我最初的想法是使用与特定div的id匹配的数组[1,4,2,3,1,4]

HTML

<div class="container">
  <div id="1" class="red square"></div>
  <div id="2" class="yellow square"></div>
  <div id="3" class="blue square"></div>
  <div id="4" class="green square"></div>
</div>

CSS

.square{
  width: 200px;
  height: 50px;
  opacity: 0.2;
}

.brighten {
  opacity: 1;
}

从这里开始,我将循环遍历数组并执行以下操作:

for( var i = 0; i < arr.length; i++){
  var element = $("#"+arr[i]);

  element.addClass('brighten');

  //pause for a half second

  element.removeClass('brighten');
}

作为JS / jQuery新手,我正在努力,因为div一次只有brighten和un brighten

  

我查看了使用jQuery animate()但是当我使用以下代码时

for (var i = 0; i < arr.length; i++) {
  $("#" + arr[i]).animate({
    opacity: 1,
  }, 500, function() {
    // Animation complete.
    $("#" + arr[i]).animate({
      opacity: 0.2,
    }, 500, function() {
        // Animation complete.
    });
  });
}
  

所有div都会立即突出显示而不是按顺序突出显示。

4 个答案:

答案 0 :(得分:1)

循环运行,并且现在完成,它不会等待你的动画,它们都会立即开始并在半秒内完成。

如果你想“错开”动画,你必须添加随每次迭代而增长的延迟

for (var i = 0; i < arr.length; i++) {
  $("#" + arr[i]).stop(true, true).delay(i*500).animate({
    opacity: 1
  }, 500, function() {
      $(this).animate({
          opacity: 0.2,
      }, 500, function() {
            // Animation complete.
      });
  });
}

答案 1 :(得分:1)

问题的原因是你正在使用的FOR循环不会等到第一盏灯变亮/变亮,然后再移动到下一盏灯。您需要找到一种链接这些行为的方法。由于jQuery animate不使用真正的Promise结构(另一次讨论),因此您可能更有效地使用回调。考虑一下:

var sequence = [1,4,2,3,1,4];
var currentIndex = 0;

// start first light
$('#' + sequence[currentIndex]).addClass('brighten');

// prepare to dim and move to next light
pauseBeforeNextLight();

/**
 * pauses, then turns off one light and turns on the next.
 */
function pauseBeforeNextLight() {
    window.setTimeout(function() {
        var $oldLight = $('#' + sequence[currentIndex]);
        $oldLight.removeClass('brighten');

        if (currentIndex >= sequence.length) {
            // we've reached the end of the sequence. Discontinue
            return;
        }

        currentIndex++; // same as currentIndex = currentIndex + 1

        // turn on the next light
        var $newLight = $('#' + sequence[currentIndex]);
        $newLight.addClass('brighten');

        // leave the new light on for 0.5s, then next. This is INSIDE the
        // timeout, so it WON'T happen immediately like in a for-loop.
        pauseBeforeNextLight() 
    }, 500);
}

这将强制程序不运行下一个灯,直到前一个灯变暗。在这个例子中,第一盏灯将在下一盏灯变亮的确切时间变暗,然后在变化之间变暗0.5秒。

答案 2 :(得分:1)

尝试使用Array.prototype.slice()复制原始数组Array.prototype.shift(),递归调用IIFE

&#13;
&#13;
var arr = [1, 4, 2, 3];

(function animate(elem) {
  var el = elem.shift();
  if (el) {
  $("#" + el).animate({
    opacity: 1
  }, 500, function() {
    $(this).animate({opacity:0.2}, 500, animate.bind(null, elem))
  })
  }
}(arr.slice(0)));
&#13;
.square {
  width: 200px;
  height: 50px;
  opacity: 0.2;
  display:inline;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="container">
  <div id="1" class="red square">1</div>
  <div id="2" class="yellow square">2</div>
  <div id="3" class="blue square">3</div>
  <div id="4" class="green square">4</div>
</div>
&#13;
&#13;
&#13;

  

我希望使用您创建的功能进行迭代   几个循环。不重复代码,我怎么能这样做?

尝试从animate函数返回jQuery .promise(),使用递归在animate

中的每个项目上调用arrays

&#13;
&#13;
var arr = [1, 4, 2, 3];
var arr2 = [2, 3, 2, 3];
var arr3 = [4, 3, 2, 3];
var arrays = [arr, arr2, arr3];
var a = arrays.slice(0);

function animate(elem) {
  var el = elem.shift();
  if (el) {
    // added `return` 
    return $("#" + el).animate({
      opacity: 1
    }, 500, function() {
      return $(this).animate({
        opacity: 0.2
      }, 500)
    // return jQuery promise object from `animate` function
    }).promise().then(animate.bind(null, elem))
  } 
}; //Need to iterate through `arrays` if possible. 
(function cycle() {
  return animate(a.shift())
  // recursively call `cycle` for each item within copy of `arrays`: `a`
  // if `a.length` is not `0`
  .then(a.length && cycle)
}())
&#13;
.square {
  width: 200px;
  height: 50px;
  opacity: 0.2;
  display: inline;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="container">
  <div id="1" class="red square">1</div>
  <div id="2" class="yellow square">2</div>
  <div id="3" class="blue square">3</div>
  <div id="4" class="green square">4</div>
</div>
&#13;
&#13;
&#13;

jsfiddle https://jsfiddle.net/ry40t266/9/

答案 3 :(得分:0)

您还可以尝试使用CSS3功能:

<!DOCTYPE html>
<html>
<head>
<style> 
#para1{
    width: 100px;
    height: 100px;
    background-color: yellow;
    -webkit-animation-name: example; /* Chrome, Safari, Opera */
    -webkit-animation-duration: 1s; /* Chrome, Safari, Opera */
    animation-name: anime1;
    animation-duration: 1s;
}

/* Chrome, Safari, Opera */
@-webkit-keyframes anime1 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}

/* Standard syntax */
@keyframes anime1 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}

#para2 {
    width: 100px;
    height: 100px;
    background-color: green;
    -webkit-animation-name: example; /* Chrome, Safari, Opera */
    -webkit-animation-duration: 5s; /* Chrome, Safari, Opera */
    animation-name: anime2;
    animation-duration: 5s;
}

/* Chrome, Safari, Opera */
@-webkit-keyframes anime2 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}

/* Standard syntax */
@keyframes anime2 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}

#para3 {
    width: 100px;
    height: 100px;
    background-color: red;
    -webkit-animation-name: example; /* Chrome, Safari, Opera */
    -webkit-animation-duration: 10s; /* Chrome, Safari, Opera */
    animation-name: anime3;
    animation-duration: 10s;
}

/* Chrome, Safari, Opera */
@-webkit-keyframes anime3 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}

/* Standard syntax */
@keyframes anime3 {
    from {opacity: 0;}
    to {opacity: 0.9;}
}
</style>
</head>
<body>


<div id="para1"></div>
<p>Text</p>
<div id="para2"></div>
<p>Text</p>
<div id="para3"></div>


</body>
</html>

这会产生一个“红绿灯”&#39;从头到尾改变不透明度,没有任何JS开始。您只需使用animation-duration属性更改效果的持续时间。注意:此示例在Internet Explorer 9及更早版本中不起作用。