2011-09-24 24 views
5

以前的问题让我想到了。是否可以模拟一个MouseEvent.CLICK,通过首先触发一个MOUSE_DOWN和一个MOUSE_UP来触发。是否可以使用鼠标向下和向上事件来模拟鼠标点击?

按照Adobe的说法。 “...对于发生的点击事件,它必须始终按照以下顺序发生:mouseDown事件,然后是mouseUp。这两个事件的目标对象必须相同;否则,click事件不会在mouseDown或mouseUp事件之间的任何时候都可能发生任何其他鼠标事件;点击事件仍然发生。 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/InteractiveObject.html#event:click

从我的测试中可以看出,CLICK事件不是由ActionScript 3事件队列构造的。或者代码有问题?

参见:

package 
{ 
import flash.display.Sprite; 
import flash.events.Event; 
import flash.events.MouseEvent; 

[SWF(backgroundColor="0xFFFFFF", frameRate="30", width="800", height="600")] 

public class Test extends Sprite 
{ 
    private var spr:Sprite = new Sprite(); 
    public function Test() 
    { 
     trace("Test()"); 
     this.addEventListener(Event.ADDED_TO_STAGE,init); 
    } 
    public function init(e:Event):void 
    { 
     trace("init()"); 
     spr.graphics.beginFill(0xFF0000); 
     spr.graphics.drawRect(0,0,200,80); 
     spr.graphics.endFill(); 
     addChild(spr); 
     addEventListener(Event.ENTER_FRAME, onEnterFrame); 
     spr.addEventListener(MouseEvent.CLICK, onClick); 
    } 
    private var tick:int = 0; 
    private function onEnterFrame(e:Event):void 
    { 
     if (tick == 1) spr.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN,true,false)); 
     if (tick == 2) spr.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP,true,false)); 
     if (tick == 3) spr.dispatchEvent(new MouseEvent(MouseEvent.CLICK,true,false)); 
     tick++; 
    } 
    private function onClick(e:MouseEvent):void 
    { 
     trace("onClick() MouseEvent.CLICK dispatched"); 
    } 
} 
} 

我应该得到两个的 'onClick()' 事件,而不是一个。

+3

你说得对。当它看到一个MOUSE_DOWN后面跟着一个MOUSE_UP时,它不会创建一个新的CLICK事件(可能是因为在事件循环代码中这样做会非常奇怪,而且在鼠标输入处理代码中生成该事件更自然)。你将不得不手动全部三个。我认为文档是指定期鼠标事件;手动触发它们,不太可能有任何特殊的代码来执行事件顺序。 – Cameron

+1

我认为这个文档有点混乱。点击事件是通过鼠标向下+鼠标在同一个对象上生成的。所有三个ActionScript事件都作为结果分派。运行时不会使用ActionScript事件本身来确定是否分派点击事件。 –

回答

3

你不能这样做的原因是所有这三种类型都是由插件创建的,并且不依赖于彼此。

只要按下交互式对象,就会触发MouseEvent.MOUSE_DOWN。 释放鼠标后立即触发MouseEvent.MOUSE_UP,它不依赖在同一个InteractiveObject中启动MOUSE_DOWN的鼠标单击操作。 只有当两个事件发生在同一个对象中时,MouseEvent.CLICK才会被触发,而光标不会在鼠标向下和鼠标向上移动的情况下离开对象。

所以你可以看到有一个简单的例子,或者两个甚至是MOUSE_DOWN和MOUSE_UP都被触发,但是CLICK不会被调用,因为事件不是CLICK。

此外,只需调度MouseEvent.CLICK事件的功能使得通过触发多个鼠标事件(当仅调用一个鼠标事件时)创建假用户交互变得毫无必要。要跟踪在鼠标下方的监听器中单击的每个对象是非常尴尬的,以便检查该监视器是否也应该触发点击。当发生ROLL_OUT事件时,您还需要删除引用。

总之,CLICK事件实际上比MOUSE_DOWN和MOUSE_UP事件多得多。它还管理事件在不离开对象的情况下连续发生在同一显示对象上。发生这种情况时,只有在发生这种情况时,闪存才会发送CLICK事件。

2

这是不可能的,这样的代码:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.KeyboardEvent; 
    import flash.events.MouseEvent; 

    /** 
    * ... 
    * @author www0z0k 
    */ 
    public class Main extends Sprite { 

     public function Main():void { 
      if (stage) init(); 
      else addEventListener(Event.ADDED_TO_STAGE, init); 
     } 

     private function init(e:Event = null):void { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 
      stage.addEventListener(MouseEvent.CLICK, onClick); 
      stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown); 
     } 

     private function onStageKeyDown(e:KeyboardEvent):void { 
      trace('pressed'); 
      stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); 
      stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));   
      stage.dispatchEvent(new MouseEvent(MouseEvent.CLICK));   
     } 

     private function onClick(e:MouseEvent):void{ 
      trace('clicked'); 
     }  
    } 
} 

输出只是:

按下
点击

一个键被按下键盘

+0

Oooo,我喜欢那个...... if(stage)... – eLouai

+0

我很好奇为什么......你会认为他们会这样做,它会让整个事件处理对我发现的错误开放。因为他们使用的不是他们所在的系统环境来构建CLICK事件而不是使用他们自己的事件。 – eLouai

+0

我不喜欢在'EventDispatcher'之外派发'Event'的可能性。如果可以的话,避免它。当开发人员想要“虚构”点击以启用菜单中的第一个按钮时,我已经看到了它,但我宁愿写一个从内部调度的函数。 – Mattias

0

不知道之后关于这个闪光灯。但是当我在学习Windows MFC时,并且一无所知。我所做的是在短暂延迟之后发送了WM_MOUSEDOWN,然后是WM_MOUSEUP。它确实有效,按钮的视觉状态也发生了变化 - 无需点击任何鼠标!

0

如果我明白你在问什么,那么答案是肯定的。

我很好奇,如果我已经过度简化了解决方案,特别是在阅读您的代码尝试后。 “模拟”鼠标点击非常简单。下面的代码在单击对象时输出两个“我已被单击”的语句,而当您向下鼠标时则输出两个语句,然后移出对象边界。

这个类扩展了我在舞台上创建的MovieClip,所以我不必编码一个盒子。

package { 

import flash.display.MovieClip; 
import flash.events.MouseEvent; 


public class clickMe extends MovieClip { 


    public function clickMe() { 
     // constructor code 

     this.addEventListener(MouseEvent.CLICK, clicked); 
     this.addEventListener(MouseEvent.MOUSE_DOWN, mDown); 

    } 

    private function clicked(e:MouseEvent):void{ 
     trace("I have been clicked"); 
     this.removeEventListener(MouseEvent.MOUSE_UP, clicked); 
    } 

    private function mDown(e:MouseEvent):void{ 
     this.addEventListener(MouseEvent.MOUSE_UP, clicked); 
    } 
} 
} 

在你的代码中,我认为,问题是,你正在试图通过它仅会触发一个事件每帧“的onEnterFrame”运行事件监听器分派 - 无法在两个。在测试你的代码之后,我不确定你试图用“tick”变量完成什么,因为你永远不会重置它。因此,MOUSE_UP事件触发一次(当tick = 2时,除非您按住鼠标),否则其他任何调度都不会再次触发。

0

不太清楚为什么每个人都在制造这些复杂的尖峰。或者,也许我只是在监督一些事情。

不管怎么说,这是一个非常简单的方法来检查:

import flash.events.MouseEvent; 

stage.addEventListener(MouseEvent.CLICK, function(){ 
    trace('clicked'); 
}); 

stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); 
stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP)); 

而答案是,“不,这是不可能的” ...

...并且可能应该跟着一个反问题:为什么我想用一系列mousedown和mouseup模拟一个点击事件,当我也可以派发一个点击事件时呢?

我是一个有生存危机的按钮吗?

还是只是出于好奇?但是你知道猫发生了什么......对,但也许它是薛定谔的猫,这意味着在这个完全无关的思路的结尾,好奇心真的没有杀死猫。

不包括如果猫出了箱子。

那么它可能只是被浪费了。

看,想出箱子可以让你死。