问题
I'm trying to use an array and for-loop to index and name some Howls and Howl trigger buttons.
I've referenced this question for what I'm trying to achieve: Howler - Random sound
The difference with mine is that it's without the random aspect plus I've added some method calls.
I'm adding the buttons used to trigger the Howls into the loop and that's where it seems to be failing - namely when the buttons are clicked.
Console reports the following when either button is clicked:Uncaught TypeError: Cannot read property 'play' of undefined
Specifically referring to this: sounds[i].play();
or sounds[i].pause();
Here's the JS:
var sounds = ['sound1', 'sound2'];
var howls = {};
for (var i=0; i<sounds.length; i++) {
howls[sounds[i]] = new Howl({
urls: ['http://powellian.com/assets/audio/' + sounds[i] + '.mp3', 'http://powellian.com/assets/audio/' + sounds[i] + '.ogg'],
volume: 1,
onplay: function() {
console.log('Playing: ' + sounds[i]);
$(sounds[i]).removeClass('static').addClass('playing');
$(sounds[i] + ' span.ascii-play').addClass('hide');
$(sounds[i] + ' span.ascii-pause').removeClass('hide');
},
onpause: function() {
console.log('Paused: ' + sounds[i]);
$(sounds[i]).removeClass('playing').addClass('paused');
$(sounds[i] + ' span.ascii-play').removeClass('hide');
$(sounds[i] + ' span.ascii-pause').addClass('hide');
},
onend: function() {
console.log('Finished: ' + sounds[i]);
$(sounds[i]).removeClass().addClass('static');
$(sounds[i] + ' span.ascii-play').removeClass('hide');
$(sounds[i] + ' span.ascii-pause').addClass('hide');
}
});
// PLAY btn
$('#' + sounds[i] + ' span.ascii-play').on('click', function (e) {
sounds[i].play();
});
// PAUSE btn
$('#' + sounds[i] + ' span.ascii-pause').on('click', function (e) {
sounds[i].pause();
});
}
I had a non-array/for-loop version working fine with 2 Howls, and the add/remove class stuff works fine so please ignore that.
I will eventually be generating 16 Howls from the array.
Here's a fiddle which includes the markup structure: Howler Fiddle
Any help would be appreciated, thanks in advance.
回答1:
There are two issues that I see here:
- You are referencing the variable
i
inside theclick
handler without maintaining scope. Because of this, it will always seei
as the last value. You could usebind
as one way of fixing this:
$('#' + sounds[i] + ' span.ascii-play').on('click', function (i2, e) {
sounds[i2].play();
}.bind(null, i));
- You are trying to call
play
onsounds
, which isn't holding the reference to theHowl
object. You should be callingplay
onhowls[sounds[i2]]
instead.
EDIT: In this case it is just easier to use a forEach
, so I've updated your fiddle to do that and fix the scoping issues here: http://jsfiddle.net/zmjz7sf3/1/.
来源:https://stackoverflow.com/questions/38212594/howler-js-referencing-and-triggering-files-from-an-array-for-loop