我正在构建一个简单的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都会立即突出显示而不是按顺序突出显示。
答案 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
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;
我希望使用您创建的功能进行迭代 几个循环。不重复代码,我怎么能这样做?
尝试从animate
函数返回jQuery .promise()
,使用递归在animate
arrays
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;
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及更早版本中不起作用。