区分用户触发事件和代码触发事件

时间:2012-04-26 10:34:59

标签: events javascript-events

我有一个包含视频的组件:<div class="component"><video src="..." /></div>

现在我想以两种方式管理播放状态:

  1. 通过点击本机播放/暂停按钮来监听可以改变的播放状态,然后用它来处理(改变组件布局,通知其他组件......)

  2. 通过让我们说myComponent.playContent()

  3. 从外部手动触发播放

    我不知道如何正确管理。例如,当用户点击原生视频控件时,会调度play事件。当我手动拨打myComponent.playContent()并调用domVideo.play()时,play事件也会被调度,所以如果我只是监听play事件,它会被混淆或被调用两次等

    问题是这里混合了两个不同的东西。

    首先,可以通过用户点击本机控件来触发回放开始,在这种情况下,我想要捕获事件,并用它做所有类型的事情。这是典型的“冒泡”,但却是流动的。

    第二次程序 - 通常是组件 - 想要以“自上而下”的方式触发回放,在这里我想区分被触发的事件以避免对待它是用户创建的游戏事件。

    我多次遇到此问题,例如在ExtJS的选项卡面板(tabchange事件)中使用制表符更改事件,我不知道如何在基于事件的编程范例中对此进行处理。

    我正在寻找一般解决方案或正确的方法。它不仅涉及原生DOM事件。我有一个YT.Player(一个YouTube播放器)对象,其自己的事件具有相同的模型,我遇到了同样的问题。

    编辑:setTimeout的一些技巧和取消是可能的,但我想避免这种情况。

1 个答案:

答案 0 :(得分:0)

我不确定DOM的细节,但是让我告诉你它如何在Flex / Flash Player中运行,它也是客户端,基于事件的运行时/编程模型。

所以让我们有一个组件C (例如,你的例子中的视频播放器)和一个应用程序A - 只是包含你的组件的东西(可能是一个子组件) - 应用程序,应用程序模块等;我们只需将其命名为 application )。

组件的公共API是这样的:

component VideoPlayer
    function play()
    event playStateChange

我将描述两种情况,一种没有MVC框架(“裸骨”解决方案),另一种情况下有MVC框架。

1)没有任何MVC框架

应用程序需要引用组件并在某处调用类似的东西:

videoPlayer.addEventListener("playStateChange", function() {...})

如果需要在VideoPlayer上开始播放,则只需调用

videoPlayer.play();

简单。

(我不明白你在问题的底部描述的问题,即为什么调用play()应该再次调度相同的事件 - 在Flex中,程序员需要明确地这样做,这可能是一个错误;当然,如果有必要,可以分配不同名称的事件,但这是另一回事。)

2)使用MVC框架

Flex应用程序通常非常大,具有深层嵌套的单独屏幕,内容窗格,容器,组件等层次结构。因此,应用程序可能无法直接引用应用程序中的所有组件。

因此,MVC框架(没有正确命名,但让我们把它放在一边......)通常提供一个中央事件总线,应用程序的不同部分可以通过它共同通信。所以有了这个框架,应用程序中任何地方的任何代码都可以这样做:

eventBus.dispatchEvent("globalPlayEvent")

并且组件(VideoPlayer)在其实例化期间会执行类似的操作:

eventBus.addEventListener("globalPlayEvent", function() {
    play();
}

相反方向的通信类似 - 组件只会在某个全局事件调度/事件总线上调度“playStateChange”,任何感兴趣的人都可以处理它。在这个模型中,你不依赖于我采取的事件冒泡。

这会回答你的问题吗?