User
User

Reputation: 13

Getting Uncaught TypeError when using var with .play() method in Howler.js

I am using howler.js to launch audio when hovering over elements on the page. To avoid duplicating the hover function for each element I figured I could just grab the id of each element, store the result in a variable and use that variable to play the corresponding audio track. The variable "track" returns the correct result in the console but when I attach it to the .play() method I get...

Uncaught TypeError: track.play is not a function
(anonymous function) @ index.html:413
b.event.dispatch @ jquery.min.js:3
v.handle @jquery.min.js:3

Here's the code (using jquery 1.9.1 and howl.js 1.1.26)

var One   = new Howl({ urls: [ 'audio/One.mp3' ] });
var Two   = new Howl({ urls: [ 'audio/02.mp3' ] });
var Three = new Howl({ urls: [ 'audio/03.mp3' ] });

$('.track').hover(function() {
  var track = $(this).attr("id");
  track.play();
  console.log(track);
}, function() {
  var track = $(this).attr("id");
  track.pause();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.26/howler.min.js"></script>

<div class="track" id="One">Track 1</div>
<div class="track" id="Two">Track 2</div>
<div class="track" id="Three">Track 3</div>

Upvotes: 1

Views: 455

Answers (1)

Will Reese
Will Reese

Reputation: 2841

You cannot use a string to reference a variable by name. The best way to handle this is going to be to create an object to hold your tracks.

var tracks = {
    One: new Howl({ urls: [ 'audio/One.mp3' ] }),
    Two: new Howl({ urls: [ 'audio/02.mp3' ] }),
    Three: new Howl({ urls: [ 'audio/03.mp3' ] })
};

$('.track').hover(function() {
    var track = $(this).attr("id");
    tracks[track].play();
    console.log(track);
}, function() {
    var track = $(this).attr("id");
    tracks[track].pause();
});

However, this is still not ideal. You could further improve it by using a data attribute to hold the track info, rather than the Id.

<div class="track" data-track="1">Track 1</div>

And then access it like this:

var track = $(this).data("track")

And then this way, you can store your tracks in an array, which is the most natural data type to use here:

var tracks = [
    new Howl({ urls: [ 'audio/One.mp3' ] }),    
    new Howl({ urls: [ 'audio/Two.mp3' ] })
];

Upvotes: 2

Related Questions