2011-09-24 78 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模擬一個點擊事件,當我也可以派發一個點擊事件時呢?

我是一個有生存危機的按鈕嗎?

還是隻是出於好奇?但是你知道貓發生了什麼......對,但也許它是薛定諤的貓,這意味着在這個完全無關的思路的結尾,好奇心真的沒有殺死貓。

不包括如果貓出了箱子。

那麼它可能只是被浪費了。

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