Frage

I'm trying to create a for loop that will reproduce the following functioning block of code, but in a much more attractive way. This is for use with the Soundcould widget API implementation found here on stackoverflow

$(document).ready(function() {
  var widget = SC.Widget(document.getElementById('soundcloud_widget'));
    widget.bind(SC.Widget.Events.READY, function() {
  console.log('Ready...');
});}

$('#goTo5').click(function()  {widget.seekTo(300000);});
$('#goTo10').click(function() {widget.seekTo(600000);});
$('#goTo15').click(function() {widget.seekTo(900000);});
$('#goTo20').click(function() {widget.seekTo(1200000);});
$('#goTo25').click(function() {widget.seekTo(1500000);});
$('#goTo30').click(function() {widget.seekTo(1800000);});
$('#goTo35').click(function() {widget.seekTo(2100000);});
$('#goTo40').click(function() {widget.seekTo(2400000);});
$('#goTo45').click(function() {widget.seekTo(2700000);});
$('#goTo50').click(function() {widget.seekTo(3000000);});  */
});

This is my non working attempt at creating the loop with the arrays to write the lines:

$(document).ready(function() {
  var widget = SC.Widget(document.getElementById('soundcloud_widget'));
    widget.bind(SC.Widget.Events.READY, function() {
  console.log('Ready...');
});

var goToId = [ "'#goTo5'", "'#goTo10'", "'#goTo15'", "'#goTo20'", '#goTo25', '#goTo30', '#goTo35', '#goTo40', '#goTo45', '#goTo50'];
var goToTime  = [ 300000, 600000, 900000, 1200000, 1500000, 1800000, 2100000, 2400000, 2700000, 300000];    

for (i=0, i<10, i++)
  {
    $(goToId[i]).click(function()
      {
        widget.seekTo(goToTime[i]);
      });
  }
});

Can anyone tell me what I've done wrong?

War es hilfreich?

Lösung

You've written a closure over the variable i, but by the time the function executes i has incremented past the bounds of the array. You can get around this by create a function which generates a new function, and passing in the enclosed variables as parameters to the outer function, like this:

var clickFunc = function(seek) {
    return function() { widget.seekTo(seek); };
}
for (i=0; i<10; i++) {
    $(goToId[i]).click(clickFunc(goToTime[i]));
}

Also, I believe you'll have to remove either the single-quotes or the double-quotes in your goToId array:

var goToId = [ "#goTo5", "#goTo10", ... ];
// or
var goToId = [ '#goTo5', '#goTo10', ... ];

Or if you prefer, you can get rid of both your arrays entirely if you write your loop like this:

var clickFunc = function(id, seek) {
    $(id).click(function() { widget.seekTo(seek); });
}
for (i = 1; i <= 10; i++) {
    clickFunc("#goTo" + (5*i), 300000 * i);
}

Or to implement the solution like what net.uk.sweet hinted at, first assign a CSS class to all your #goToN elements, say .goToButton like this (I used <a> elements for demonstration, but the actual type of element you use isn't important):

<a id="goTo5" class="goToButton" href="#">5</a>
<a id="goTo10" class="goToButton" href="#">10</a>
<a id="goTo15" class="goToButton" href="#">15</a>
...

Then use the jQuery each method:

$('.goToButton').each(function(i) {
    $(this).click(function() {
        widget.seekTo(300000 * (i+1));
    });
});

Note that this depends on the elements you're binding to being in the correct order within the document. If they are not in order, you may have to make adjustments to this script.

Andere Tipps

Even if Javascript is a really large-minded language, you have to add the var prefix in your loop parameters :

for(var i = 0; i < 10; i++)

Edit #1 :

Just saw you added some ' to your selectors :

"'#goTo5'"

Should be :

"#goTo5"

Or :

'#goTo5'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top