Why audio events are not firing with BackboneJS but others are?

I don't understand why the click events are firing ok but not the timeupdate one.

No event is firing from <audio>, I tried with canplay, play, pause, timeupdate, ... If I display the controls in the template a click .audio event will fire if I click on the player though.

var PlayerView = Backbone.View.extend({
    tagName : 'div',

    template: _.template($('#player-template').html()),

    initialize: function() {

    events: {
        'timeupdate .audio': 'onTimeUpdate',
        'click .btn_play': 'onClickPlay',
        'click .btn_pause': 'onClickPause'

    onTimeUpdate: function () {
        console.log('player ' + this.model.get('id') + ' : event = onTimeUpdate');

    onClickPlay: function () {
        console.log('player ' + this.model.get('id') + ' : event = onClickPlay');

    onClickPause: function () {
        console.log('player ' + this.model.get('id') + ' : event = onClickPause');


    var model = new PlayerModel({'id' : 1});
    var view = new PlayerView({'model' : model});

The template :

<script type="text/template" id="player-template">
    <div id="player<%= id %>" class="player">
        <audio class="audio">
          <source src="<%= track_url %>" type="audio/mp3" />
        <div class="control">
            <button class="btn_play">Play</button>
            <button class="btn_pause">Pause</button>



Backbone internally converts the events object and binds the events by delegation. This means that

events: {
        'timeupdate .audio': 'onTimeUpdate',
        'click .btn_play': 'onClickPlay'

ends as

this.$el.delegate('.audio','timeupdate', this.onTimeUpdate);
this.$el.delegate('.btn_play','click', this.onClickPlay);

But there's a catch:

Uses event delegation for efficiency. [...] This only works for delegate-able events: not focus, blur, and not change, submit, and reset in Internet Explorer.

And it would appear that audio events are not delegate-able.

However, setting directly the callbacks does work, for example you could replace your initialize function by

initialize: function() {
    this.$('.audio').on('timeupdate', this.onTimeUpdate);


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.