【问题标题】:Catching all audio end events from dynamic content in jquery从jquery中的动态内容中捕获所有音频结束事件
【发布时间】:2015-04-19 09:58:26
【问题描述】:

我见过类似的问题 - 但不能解决我的问题!

我的页面上有音频,当一个结束时,我希望下一个开始,但我什至无法触发结束...

我将代码缩减为:

function DaisyChainAudio() {
    $().on('ended', 'audio','' ,function () {
        alert('done');
    });
}

这是从我的页面/代码中调用的(并被执行,设置断点显示)。

据我所知,这应该在文档级别设置处理程序,因此任何“音频”标签(即使是动态添加)的任何“结束”事件都应该被捕获并向我显示警报...

但它永远不会触发。

编辑

到目前为止,从 Çağatay Gürtürk 的建议中借鉴了一些...

function DaisyChainAudio() {
        $(function () {
        $('audio').on('ended', function (e) {
            $(e.target).load();
            var next = $(e.target).nextAll('audio');
            if (!next.length) next = $(e.target).parent().nextAll().find('audio');
            if (!next.length) next = $(e.target).parent().parent().nextAll().find('audio');
            if (next.length) $(next[0]).trigger('play');
        });
    });
}

我仍然想在文档级别设置它,这样我就不用担心在添加动态元素时添加它...

【问题讨论】:

  • 当您致电.on() 时,音频标签是否已经可用? jquery.com 说:“事件处理程序仅绑定到当前选定的元素;它们必须在您的代码调用 .on() 时存在。”
  • 碰巧他们就是这样。但据我了解 $().on 会将事件附加到文档根目录 - 所以任何结束(即使是动态添加的标签)都会冒泡并被捕获。

标签: javascript jquery audio html5-audio


【解决方案1】:

它不触发的原因是媒体事件(那些专门属于 audiovideo 的事件,例如 playpausetimeupdate 等)不要冒泡。您可以在this question 的答案中找到对此的解释。

所以使用他们的解决方案,我捕获了ended 事件,这将允许为动态添加的音频元素设置触发器。

$.createEventCapturing(['ended']);  // add all the triggers for which you like to catch.
$('body').on('ended', 'audio', onEnded); // now this would work.

JSFiddle demo

事件捕获代码(取自另一个 SO 答案):

    $.createEventCapturing = (function () {
        var special = $.event.special;
        return function (names) {
            if (!document.addEventListener) {
                return;
            }
            if (typeof names == 'string') {
                names = [names];
            }
            $.each(names, function (i, name) {
                var handler = function (e) {
                    e = $.event.fix(e);

                    return $.event.dispatch.call(this, e);
                };
                special[name] = special[name] || {};
                if (special[name].setup || special[name].teardown) {
                    return;
                }
                $.extend(special[name], {
                    setup: function () {
                        this.addEventListener(name, handler, true);
                    },
                    teardown: function () {
                        this.removeEventListener(name, handler, true);
                    }
                });
            });
        };
    })();

【讨论】:

    【解决方案2】:

    试试这个:

    $('audio').on('ended', function (e) {
            alert('done');
            var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
    });
    

    请注意,当您动态创建新音频时,您应该分配事件。一个快速而肮脏的解决方案是:

    function bindEvents(){
    $('audio').off('ended').on('ended', function (e) {
                alert('done');
                var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
        });
    }
    

    并在您创建/删除音频元素时运行 bindEvents。

    【讨论】:

    • 您好,您知道为什么不能像其他事件一样在文档级别设置吗?到目前为止,我已经设法将“显示”和“行为”分开。在添加动态内容之前在文档级别设置所有“行为”。
    • 尝试 $(document).on('end', 'audio', function (e) { alert('done'); });但据我所知,文档级别的事件并不是那么好。我总是使用我在回答中写的方法。
    • 谢谢 - $().on 对其他一切都有效 - 也许音频有问题......但我使用了你的建议,所以打勾:)
    猜你喜欢
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多