Note: in all comments, this answer has changed dramatically. Please view earlier versions if you want to see the evolution of this answer.
After receiving the JsFiddle example, I was able to make it work as you think.
Working demo
HTML:
<body> <div id="wrapper"> <div id="player-placeholder"></div> <script id="player-template" type="text/x-handlebars-template"> {{#each tracks}} <div class="track"> <header class="header"> <span class="artist">{{user.username}}</span> - <span class="title">{{title}}</span> </header> <section class="player" data-uri="{{permalink_url}}"> </section> </div> {{/each}} </script> </div> </body>
JavaScript:
$(document).ready(function() { var source = $('#player-template').html();
Something went wrong?
JavaScript is a single-threaded, asynchronous, event-driven language. This gigantic appetite means that JavaScript really has no concept of threads (I intentionally ignore WebWorkers). To get around this limitation, almost all JavaScript IOs are non-blocking (asynchronous).
Whenever an asynchronous I / O transaction begins, it immediately returns to the caller, and code execution continues. Almost all I / O transactions accept a βcallbackβ or have an event that will be raised when the I / O transaction completes. This means that the basic pattern for all I / O follows something like this:
- Create callback function
- Call an I / O operation by passing it the arguments it needs, plus a callback
- Execution returns immediately
- Sometime in the future, the callback function is called
In your original example, the $(document).ready(function() { ... }) queue calls an anonymous function when the document.onReady event fires. However, in your original example, two calls were assigned. This is not a problem, in fact .ready(...) designed to accept and queue many callbacks. However, when you did wrong, you have two separate blocks of code called SC.get(...) .
Technically, if this is done correctly, this will not be a problem, but your first in the finished callback was instructed to customize the HTML pages, while your second callback tried to initialize the html-based player controls on the page. Remember that these events and I / O are asynchronous; they fire in any order. Essentially, it became a time issue, you tried to initialize the controls on the page and generate HTML code to display on the page at the same time.
How was fixed
To fix the synchronization problem, you need to synchronize when you receive information, when you build the HTML template and when you initialize your controls. There are many ways to do this, and many frameworks support the idea of promises in order to gain control over the order in which asynchronous events are triggered and the calls being called.
I took a simple route and combined all of your SC.get calls into one, and then in its callback I process the handlebars template and initialize the SoundCloud players.