我猜是这样的。我没有检查它,所以请原谅我的任何错别字。但从理论上讲,这应该可以解决问题。正如我在上面所说的,唯一要做的就是在您收听它的任何地方用DoubleClick.DOUBLE_CLICK替换MouseEvent.DOUBLE_CLICK ,它会神奇地工作。大概。
package
{
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.events.MouseEvent;
public class DoubleClick
{
// Don't occasionally set it to actual MouseEvent.DOUBLE_CLICK
// because you'll get twice as many events on the platforms
// where original MouseEvent.DOUBLE_CLICK actually works.
static public const DOUBLE_CLICK:String = "custom.double";
// How far the Mouse can click for the second time so that
// it will still count as double click (in pixels).
static public const distanceTreshold:int = 5;
// How fast the second click has to happen for these two clicks
// to still be considered a double click (in milliseconds).
static public const timeoutTreshold:int = 500;
static private var stage:Stage;
// Call it to initialize the custom double click engine.
static public function attachTo(target:Stage):void
{
stage = target;
stage.addEventListener(MouseEvent.CLICK, onClick);
Click.stage = stage;
}
static private var lastClick:Click;
static private function onClick(e:MouseEvent):void
{
// Sanity check. If the event target is not attached to
// the display list then it is pointless to proceed.
if (!e.target.stage)
{
if (lastClick)
{
lastClick.destroy();
lastClick = null;
}
return;
}
var aClick:Click = new Click(e.target as DisplayObject);
if (!lastClick)
{
// If there was no previous clicks then just remember this one.
lastClick = aClick;
}
else if (checkDouble(aClick))
{
// Yay! Double click seems to happen!
dispatchDouble(aClick, e);
}
else
{
// If these two clicks don't qualify as double, just
// forget the previous one and remember the new one.
lastClick.destroy();
lastClick = aClick;
}
}
// Return true if the second click was fast enough and close enough.
static private function checkDouble(click:Click):Boolean
{
if (Math.abs(click.x - lastClick.x) > distanceTreshold) return false;
if (Math.abs(click.y - lastClick.y) > distanceTreshold) return false;
if (click.time - lastClick.time > timeoutTreshold) return false;
return true;
}
static private function dispatchDouble(click:Click, e:MouseEvent):void
{
// Get the bottommost display object as a
// starting point for the double click event,
// because between the first and second clicks
// some other objects could appear or disappear
// under the mouse, so the second click might not
// actually be the second for the designated target.
var aTarget:DisplayObject = lastClick.deepestCommon(click);
// Compose the event.
var anEvent:MouseEvent = new MouseEvent
(
DOUBLE_CLICK, // Event.type
true, // Event.bubbles
false, // Event.cancelable
e.localX, // Copies of original event properties.
e.localY,
e.relatedObject,
e.ctrlKey,
e.altKey,
e.shiftKey,
e.buttonDown,
e.delta,
e.commandKey,
e.controlKey,
2 // MouseEvent.clickCount
);
// Clean up things.
lastClick.destroy();
lastClick = null;
click.destroy();
// Emulate the double click event.
aTarget.dispatchEvent(anEvent);
}
}
}
import flash.utils.getTimer;
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
// This is basically a data structure to keep
// basic information about a single click.
internal class Click
{
static public var stage:Stage;
public var x:int;
public var y:int;
public var time:int;
public var path:Array;
public function Click(target:DisplayObject)
{
x = stage.mouseX;
y = stage.mouseY;
time = getTimer();
path = [target];
// Unwind the full path from stage to the target.
var aParent:DisplayObjectContainer = target.parent;
while (aParent)
{
path.unshift(aParent);
aParent = aParent.parent;
}
// At this point the path should contain something like
// [stage, .. , .. , .. , target.parent, target]
}
// Release the path Array.
public function destroy():void
{
if (path)
{
path.length = 0;
path = null;
}
}
// Returns the deepest DisplayObject that
// both click passed through along their ways.
public function deepestCommon(click:Click):DisplayObject
{
// At very least they have stage as the common point.
var result:DisplayObject = path[0];
for (var i:int = 1; i < Math.min(path.length, click.path.length); i++)
{
if (path[i] != click.path[i]) break;
result = path[i];
}
return result;
}
}