Отличный вопрос! Сам долго задавался этой проблемой. Как бекендщик, понимал необходимость но не знал как реализовать структуру, чтобы не было каши.
Решение, которое помогло: нужно добиться того, чтобы в PlayerApp вообще не было обращений в DOM. Кстати, тогда и jQuery не нужен будет внутри PlayerApp. Там должно быть только контекст аудио, ноды, аналайзер и проч. Вот только это сделает код
намного проще, чище и понятнее.
Например, PlayerApp.js может выглядеть так
(function() {
var PlayerApp, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments) } }
PlayerApp = (function() {
function PlayerApp(url) {
this.play = __bind(this.play, this)
// другие __bind здесь, stop, resume, etc...
this.audio = new Audio()
this.audio.volume = 1
this.audio.src = url
this.audio.addEventListener("canplaythrough", this.canplay, false)
// другие addEventListener здесь: loadedmetadata, timeupdate, etc...
}
Track.prototype.play = function() {
this.audio.play()
if (typeof this.onplay_callback == "function") { this.onplay_callback() }
}
// другие функции здесь ....
return PlayerApp
})()
window.PlayerApp = PlayerApp
}).call(this)
А где-то в app.js будет графическая часть :
player = new PlayerApp()
player.onplay_callback = function() {
$("#main-play-btn").toggleClass('play')
$(".playlist-play-btn").toggleClass('play')
}
Таким образом, где бы ни запустили плей (кнопка в плеере, по центру экрана или пробелом на клавиатуре) отрисовка идет через одно место - колбэк onplay_callback. Через одно место ;) Смешно, но это очень упростило код мне.
Еще отлично организовано в Яндексе, посмотрите
пример. Очень рекомендую.