为什么 BackboneJS 不触发音频事件,而其他事件触发? [英] Why audio events are not firing with BackboneJS but others are?

查看:18
本文介绍了为什么 BackboneJS 不触发音频事件,而其他事件触发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么 click 事件可以正常触发,而 timeupdate 事件不是.

<audio> 没有触发任何事件,我尝试使用 canplay、play、pause、timeupdate,...如果我在模板中显示控件,但是如果我单击播放器,则会触发 click .audio 事件.

var PlayerView = Backbone.View.extend({标签名称:'div',模板:_.template($('#player-template').html()),初始化:函数(){this.$el.html(this.template(this.model.toJSON()));}事件:{'timeupdate .audio': 'onTimeUpdate','点击 .btn_play': 'onClickPlay','点击 .btn_pause': 'onClickPause'},onTimeUpdate: 函数 () {console.log('player' + this.model.get('id') + ': event = onTimeUpdate');},onClickPlay: 函数 () {console.log('player' + this.model.get('id') + ': event = onClickPlay');},onClickPause: 函数 () {console.log('player' + this.model.get('id') + ': event = onClickPause');},});$(函数(){var model = new PlayerModel({'id': 1});var view = new PlayerView({'model' : model});$("#players").append(view.el);})

模板:

解决方案

Backbone 在内部转换事件对象和 通过委托绑定事件.这意味着

事件:{'timeupdate .audio': 'onTimeUpdate','点击 .btn_play': 'onClickPlay'}

结束于

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

但有一个问题:

<块引用>

使用事件委托来提高效率.[...] 这仅适用于可委托事件:不聚焦、模糊、不改变、提交和在 Internet Explorer 中重置.

而且音频事件似乎不能委托.

但是,直接设置回调确实有效,例如您可以将初始化函数替换为

初始化:函数(){this.$el.html(this.template(this.model.toJSON()));_.bindAll(this,'onTimeUpdate');this.$('.audio').on('timeupdate', this.onTimeUpdate);}

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() {
        this.$el.html(this.template(this.model.toJSON()));
    }

    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');
    },

});


$(function(){
    var model = new PlayerModel({'id' : 1});
    var view = new PlayerView({'model' : model});
    $("#players").append(view.el);
})

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" />
        </audio>
        <div class="control">
            <button class="btn_play">Play</button>
            <button class="btn_pause">Pause</button>
        </div>
    </div>
</script>

解决方案

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.$el.html(this.template(this.model.toJSON()));
    _.bindAll(this,'onTimeUpdate');
    this.$('.audio').on('timeupdate', this.onTimeUpdate);
}

这篇关于为什么 BackboneJS 不触发音频事件,而其他事件触发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆