使用动态构建的 jQuery 承诺链按顺序激活特定元素



我正在尝试播放声音并按特定顺序切换特定元素的类。每个元素都应该添加一个类,播放一个声音,然后删除该类,然后再继续对下一个元素执行相同的操作。

以下是执行此操作的一种方法:

var delay = 400;
$('#green').toggleClass('active').delay(delay).promise().done(function () {
  playSound(this[0].id);
  $(this).toggleClass('active');
  $('#red').toggleClass('active').delay(delay).promise().done(function () {
    playSound(this[0].id);
    $(this).toggleClass('active');
    $('#blue').toggleClass('active').delay(delay).promise().done(function () {
      playSound(this[0].id);
      $(this).toggleClass('active');
      $('#yellow').toggleClass('active').delay(delay).promise().done(function () {
        playSound(this[0].id);
        $(this).toggleClass('active');
      });
    });
  });
});

我宁愿简单地传入一个元素 ID 数组来动态生成上述代码。基于这里的很多相关答案,我相信这段代码更朝着正确的方向发展,但一切都一下子运行。

startAnimation();
function playSound(color) {
  var sound = document.getElementById(color + 'Sound');
  sound.load();
  sound.play();
}
function computerClick(color) {
  playSound(color);
  $('#' + color).toggleClass('active').delay(500).promise().done(function () {
    $('#' + color).toggleClass('active');
  });
}
function startAnimation() {
  var colors = ['green', 'red', 'blue', 'yellow'];
  var p = $.when(1);
  var results = [];
  colors.forEach(function(color) {
    p = p.then(function() {
      return computerClick(color);        
    });
  });
}

JS小提琴

这里有人可以告诉我我做错了什么,或者我是否需要一种完全不同的方法?

你可以利用.queue()来按顺序链接jQuery承诺。注意,在 jsfiddle js green 作为参数传递给playSound(),尽管green似乎没有定义?

在元素.play() audio之前添加了.load(); return语句从computerClick()返回 jQuery promise 对象

$(function() {
startAnimation();
function playSound(color) {
  var sound = document.getElementById(color + 'Sound');
  sound.load(); sound.play();
}
function computerClick(color) {
  playSound(color);
	return $('#' + color).toggleClass('active').delay(500, "_fx")
           .dequeue("_fx")
           .promise("_fx").done(function () {
             $('#' + color).toggleClass('active');
           });
}
function startAnimation() {
  var colors = ['green', 'red', 'blue', 'yellow'];
  var results = [];
  $({}).queue("_fx", $.map(colors, function(el) {
    return function(next) {
      computerClick(el).then(next)     
    } 
  })).dequeue("_fx")  
}
playSound("green");
})
.color-button {
  width: 200px;
  height: 200px;
  display: inline-block;
}
.active {
  opacity: 1!important;
}
#blue {
  background-color: blue;
  opacity: .6;
}
#yellow {
  background-color: yellow;
  opacity: .6;
}
#green {
  background-color: green;
  opacity: .6;
}
#red {
  background-color: red;
  opacity: .6;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="color-button" id="green"></div>
<div class="color-button" id="red"></div>
<div class="color-button" id="yellow"></div>
<div class="color-button" id="blue"></div>
<audio id="greenSound" preload="auto" src="#" type="audio/wav"></audio>
<audio id="redSound" preload="auto" src="#" type="audio/wav"></audio>
<audio id="yellowSound" preload="auto" src="#" type="audio/wav"></audio>
<audio id="blueSound" preload="auto" src="#" type="audio/wav"></audio>

JSFIDDLE https://jsfiddle.net/xnr3xpv5/2/

最新更新