从非DOM对象内部调度和处理自定义事件

Dispatching and handling a custom event from inside non-DOM object

本文关键字:处理 自定义 事件 调度 DOM 对象 内部 从非      更新时间:2023-10-22

我的应用程序需要连接到网络视频,与之同步,并使用它。我正在我的应用程序和它可能遇到的所有网络视频播放器之间编写一个接口类。接口类将确定它正在处理的视频播放器类型,针对适合该播放器的播放器对象设置侦听器,并发送规范化的事件供我的应用程序侦听。例如,可以向支持html5的视频播放器请求.currentTime,而Youtube Flash API则接受请求.getCurrentTime()

在下面的示例中,接口类正在侦听诸如playingseeking之类的事件,一旦它听到这样的事件,它就会发出自己的事件。它上面的层会监听来自界面的事件,并调用我的应用程序中的相应函数。

代码
在我的应用程序和接口类之间的层中:

var inter = new VideoInterface( TargetVideoId );
inter.addEventListener("playing", function(){ // Doesn't compile
    console.log('Heard playing from interface...');
}, false );
$(inter).bind( "isPlaying", function(evt) { // Doesn't do anything
    console.log('Heard playing from interface...');
    myApp.start();
});

VideoInterface类,在定位HTML5播放器后添加侦听器和处理程序:

$(vidId).bind({ 
    seeking: function() {
    console.log('Heard seeking, dispatching event...');
        var e = $.event({
            type: "isSeeking",
            message: "stuff",
            date: new Date()
        });
        $.trigger(e);
    }, 
    playing: function() {
    console.log('Heard playing, dispatching event...');
        $.event.trigger({
            type: "isPlaying",
            message: "stuff",
            date: new Date()
        });         
    },
    pause: function() {
    console.log('Heard pause, dispatching event...');
        $.event.trigger({
            type: "isPaused",
            message: "stuff",
            date: new Date()
        });
    }
});

问题
我不确定侦听器是没有侦听,还是事件没有触发,但无论如何,从接口类内部触发的事件没有到达中间层,它们将被传递到我的应用程序。Heard playing, dispatching event...等是我在控制台中看到的唯一消息——在中间层捕获事件时触发的消息不会出现。我读到过,在这种情况下,你不能将事件侦听器附加到变量或对象,但如果是这样,我该如何实现我想要的效果(同样,就是让一个对象发送一个任何侦听它的东西都能捕捉到的事件)?

编辑
我已经通过向VideoInterface类添加bindListenersFor( obj )方法解决了我的问题。obj是对我的应用程序的引用,接口已经有了对视频对象的内部引用。代码现在看起来像这样:

var inter = new VideoInterface( videoReference );
var app = new App( inter );
inter.bindListenersFor( app );

相关接口代码:

bindListenersFor : function( obj ) {
    thisClass = this;
    $(this.videoHandle).bind({ 
        seeking: function() {
            obj.seek( thisClass.getCurTime() ); 
        }, 
        playing: function() {
            obj.start();
        },
        pause: function() {
            obj.pause();
        }
    });
},
play : function() {
    this.videoHandle.play();
},
pause : function() {
    this.videoHandle.pause();
},
{ ... }

现在,由于在应用程序本身加载后,对主应用程序对象的引用被传递到接口中(接口已经是参数之一),两者可以相互交谈。尽管如此,这让人觉得有些不雅,所以发送和侦听自定义变量事件的问题仍然悬而未决。

我将不再尝试通过jQuery绑定到事件,而是自己处理这些自定义事件。

只要创建一个空的方法数组,以便在事件X发生时调用。

换句话说:

function VideoInterface() {
  this.isPlayingHandlers = [];
}
var inter = new VideoInterface( TargetVideoId );    
inter.isPlayingHandlers.push(function(data) { 
    console.log('Heard playing from interface...');
});
// inside the .bind()
playing: function() {
    console.log('Heard playing, dispatching event...');
        var eventData = 'blah';
        for (var handler in inter.isPlayingHandlers)
           handler(eventData);
}

您尝试使用的方法用于DOM事件。您可以使用回调而不是事件,也可以实现类似于节点的EventEmmiter之类的东西。