Event.MOUSE_LEAVE在 Actionscript 3 中很棒,但如果用户按住左(或右)鼠标按钮,它似乎不会触发。
有没有办法检测鼠标按住时鼠标是否离开 Flash 电影?或者如果它是在 Flash 电影之外发布的?
Event.MOUSE_LEAVE在 Actionscript 3 中很棒,但如果用户按住左(或右)鼠标按钮,它似乎不会触发。
有没有办法检测鼠标按住时鼠标是否离开 Flash 电影?或者如果它是在 Flash 电影之外发布的?
要获得所有这些,需要一点技巧。您必须存储鼠标是否离开舞台并Event.MOUSE_LEAVE
相应地处理事件。这样做可以为您提供所有正常的鼠标功能,包括不会因为鼠标离开舞台而停止拖动。由于用户可能会回到舞台上并继续拖动,因此它会一直等待,直到用户在舞台上或舞台外释放鼠标。
var mouseOffStage:Boolean;
var bonk:YourDisplayObject = new YourDisplayObject()
addChild(bonk);
bonk.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
mouseOffStage = false;
bonk.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
})
private function mouseUp(e:MouseEvent) :void {
trace("Mouse Up On Stage")
bonk.stopDrag()
}
private function mouseLeave(e:Event) :void {
if(mouseOffStage){
trace("mouse up and off stage");
bonk.stopDrag();
}else{
trace("mouse has left the stage");
//no reason to stop drag here as the user hasn't released the mouse yet
}
}
private function mouseOut(e:MouseEvent) :void {
mouseOffStage = true;
trace("mouse has left the stage")
}
private function mouseOver(e:MouseEvent) :void {
mouseOffStage = false;
trace("mouse has come back on stage");
}
hack 是MOUSE_LEAVE
事件,而不是MOUSE_UP
事件,在鼠标离开舞台时被触发,所以你必须跟踪鼠标在释放时是否已经离开舞台。
拖动完成后,您当然希望删除与检测鼠标移出和鼠标抬起相关的所有事件侦听器,但为了便于阅读,该代码被省略了。
这就是我所做的:
mc.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
private function onMouseDown(_e:MouseEvent):void
{
mc2.startDrag(params);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
}
private function onMouseUp(_e:MouseEvent):void
{
ms2.stopDrag();
}
private function onMouseLeave(_e:Event):void
{
mc2.stopDrag();
}
private function onMouseOut(_e:MouseEvent):void
{
if (e.stageX <= 0 || e.stageX >= stage.stageWidth || e.stageY <= 0 || e.stageY >= stage.stageHeight)
{
mc2.stopDrag();
}
}
这里有几个棘手的陷阱不要落入:
一件奇怪的事情是,在 Chrome + Firefox 中,MOUSE_LEAVE 事件不会为or的WMODE调度。它只是不会触发 - 鼠标向下或向上。OPAQUE
TRANSPARENT
有了WINDOW
它可以正常工作。那个我花了很长时间才发现!grr ... http://bugs.adobe.com/jira/browse/FP-892
其次,确保您使用的是处理程序Event
的参数类型,Event.MOUSE_LEAVE
而不是MouseEvent
. 如果您尝试处理MOUSE_LEAVE
,e:MouseEvent
您将收到一个您可能永远看不到的错误(除非您使用的是调试 Flash 播放器)。这是一个非常容易犯的错误,因为您可能将所有其他处理程序都指向相同的方法。
这就是我所做的:(只需endDrag
从mouseLeave(e:Event)
stage.addEventListener(MouseEvent.MOUSE_MOVE, drag);
stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
stage.addEventListener(Event.DEACTIVATE, endDrag);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
private function mouseLeave(e:Event):void
{
endDrag(new MouseEvent("MOUSE_LEAVE"));
}
public function endDrag(evt:MouseEvent):void
{
/// handle end drag
}
我在必须构建到 Flex 应用程序中的 PDF 类型查看器中遇到了类似的问题。即使鼠标离开舞台或浏览器窗口,我希望平移功能仍然有效。以下是我完成此操作的方法,我更改了代码以删除对 Flex 框架类的引用,因此这应该适用于任何 AS3 项目。我mouseDown
会开始在计时器上跟踪这些值。 _client
可以是flash.display.DisplayObject
目标阶段中的任何一个。在我的情况下,它是一个 Flexmx.controls.SWFLoader
对象,但在你的情况下,我想它是拖动目标:
private function get currentMouseX():Number
{
return _client.stage.mouseX;
}
private function get currentMouseY():Number
{
return _client.stage.mouseY;
}
stage.mouseX
和值是相对于舞台定义的stage.mouseY
,无论鼠标是在舞台上还是在浏览器窗口中(至少在 Flash Player 10 中,我还没有在早期的 Flash 播放器版本中测试过)。要查看鼠标是否在舞台外,只需测试并查看这些值是否在舞台内,如下所示:
if (currentMouseY < 0 ||
currentMouseY > _client.stage.height ||
currentMouseX < 0 ||
currentMouseX > _client.stage.width)
{
// Do something here
}
编辑:关于检测mouseUp
舞台外的事件,如果你在舞台上注册了一个监听器,即使事件发生在舞台或浏览器之外,也会发出 mouseUp 。这是我如何处理事件函数的代码以供参考。_client
对象可以是flash.display.DisplayObject
任何:
// attach the events like so when you initialize
_client.addEventListener(MouseEvent.MOUSE_DOWN , handleMouse);
_client.addEventListener(MouseEvent.MOUSE_OUT , handleMouse);
_client.addEventListener(MouseEvent.MOUSE_OVER , handleMouse);
//
// and handle them like this:
private function handleMouse(e:MouseEvent):void
{
switch(e.type)
{
case "mouseDown":
// add listeners, notice the mouse move and mouse up are
// attached to the stage, not the display object this way
// events are issued regardless of whether the mouse is in
// the stage or even within the browser window
_client.stage.addEventListener(MouseEvent.MOUSE_UP, handleMouse);
_client.addEventListener(MouseEvent.CLICK, handleMouse);
_client.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouse);
// remove listeners
_client.removeEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
//
// commands / actions
break;
case "mouseUp":
// add listeners
_client.addEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
// remove listeners
_client.stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouse);
_client.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouse);
// commands/actions
break;
case "click":
// add listeners
_client.addEventListener(MouseEvent.DOUBLE_CLICK, handleMouse);
// remove listeners
_client.removeEventListener(MouseEvent.CLICK, handleMouse);
// commands / actions
break;
case "mouseMove":
// add listeners
// remove listeners
_client.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouse);
_client.removeEventListener(MouseEvent.CLICK, handleMouse);
// commands
break;
case "mouseOut":
// add listeners
// remove listeners
// commands / actions
break;
case "mouseOver":
// add listeners
// remove listeners
// commands /actions
break;
}
}
编辑:删除了对 Flex 框架类的引用 编辑:我记得当应用程序在 Mac OSX 上的 Safari 浏览器中运行时,浏览器窗口之外的事件可能存在一些问题。如果您使用它,请确保在该浏览器中测试此代码。这在我的应用程序中不是问题,所以我没有进一步研究这个问题。
如果您在拖动 MovieClip 的地方做某事,这似乎工作得很好。
stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
编辑 - 没关系
有没有办法检测鼠标按住时鼠标是否离开 Flash 电影?
从来没听说过
或者如果它是在 Flash 电影之外发布的?
Event.MOUSE_LEAVE 确实在您释放时发生。
更多信息在这里 http://blog.zupko.info/?p=3 见 JIMISAACS 评论。
var youMax_X:Number; //set this var to Max x
var youMax_Y:Number; //set this var to `enter code here`Max y
var dragBounds:Rectangle = new Rectangle(0,0,youMax_X,yourMax_Y);
stage.addEventListener(MouseEvent.MOUSE_DOWN,handleDown);
stage.addEventListener(MouseEvent.MOUSE_UP,handleUp);
private function handleDown(e:Event):void{
this.startDrag(false,dragBounds);
}
private function handleUp(e:Event):void{
this.stopDrag();
}
这是正确的答案。您将 DisplayObject 传递给的自定义类并将其拖动到鼠标向上或鼠标移出舞台。随意定制:
package fanlib.gfx
{
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.ui.Mouse;
public class Drag
{
private var obj:DisplayObject;
private var point:Point = new Point();
private var stg:Stage;
public function Drag(obj:DisplayObject)
{
this.obj = obj;
stg = Stg.Get();
stg.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stg.addEventListener(MouseEvent.MOUSE_UP, stopDrag);
//stg.addEventListener(Event.MOUSE_LEAVE, stopDrag); // sh*t just won't fire
point.setTo(stg.mouseX, stg.mouseY);
}
private function mouseMove(e:MouseEvent):void {
if (stg.mouseX <= 0 ||
stg.mouseY <= 0 ||
stg.mouseX >= stg.stageWidth ||
stg.mouseY >= stg.stageHeight) {
stopDrag();
return;
}
obj.x += stg.mouseX - point.x;
obj.y += stg.mouseY - point.y;
point.setTo(stg.mouseX, stg.mouseY);
}
public function stopDrag(e:* = null):void {
stg.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stg.removeEventListener(MouseEvent.MOUSE_UP, stopDrag);
//stg.removeEventListener(Event.MOUSE_LEAVE, stopDrag);
}
}
}