2010-01-06 139 views
2

我正在构建一个加载外部SWF的专用查看器应用程序。如何检查鼠标是否可以点击?

var content:Sprite = ... 
content.addChild(loader); 

我听我的顶级内容Sprite MOUSE_OVER和MOUSE_OUT事件。 over处理程序隐藏默认光标并显示一个自定义(缩放)光标。 输出处理程序将光标变回默认值。

当鼠标位于外部加载的SWF中的可点击项目(如按钮或文本链接)上时,我想要实现的不是显示缩放光标。

当前代码完美适用于AVM1 swfs。 问题在于使用AS3加载的swfs。 对于这些内容MOUSE_OUT被触发,并立即触发MOUSE_OVER,所以光标仍然是错误的。

这可能归结为:如何检查鼠标是否超过可点击的内容子项?

回答

0

随着一些测试和乔治给我的暗示,这是内容MOUSE_OVER监听我只写(在haXe的),这似乎工作:

public var mouseOverClickableContent:Bool; 

private function onOverContentChild(event) 
{ 
    mouseOverClickableContent = false; 
    if (event.target != content) 
    { 
     var obj:flash.display.InteractiveObject = cast event.target; 

     while (obj != content) 
     { 
      if ( obj.hasEventListener(flash.events.MouseEvent.CLICK) 
       || obj.hasEventListener(flash.events.MouseEvent.MOUSE_UP) 
       || obj.hasEventListener(flash.events.MouseEvent.MOUSE_DOWN) 
       || (Std.is(obj, Sprite) && cast(obj, Sprite).buttonMode) 
      ){ 
       mouseOverClickableContent = true; 
       break; 
      } 
      obj = obj.parent; 
     } 
    } 


} 

遗憾的是,似乎有没有办法检测鼠标是否在TextField htmlText链接上,所以我可以在那里添加一个TextField htmlText.indexOf("<a") != -1检查。

除非有人知道检测mouse-over-textfield-links的技巧吗?

4

好问题!

我做了一个快速测试。有一种称为getObjectsUnderPoint()方法,其

返回位于 指定点下,并且是 孩子(或孙子,等等)对象的数组该DisplayObjectContainer的 实例

根据到文档。

而且

是 无法进入安全考虑任何子对象 从返回数组省略。到 确定此安全 限制是否影响返回 阵列,调用 areInaccessibleObjectsUnderPoint() 方法。

所以我不知道这可能有多大的帮助。

这里是我的测试还是:

//make some clips interactive 
for(var i:int = 0 ; i < numChildren ; i+=2){ 
    MovieClip(getChildAt(i)).mouseEnabled = true; 
    MovieClip(getChildAt(i)).buttonMode = true; 
    MovieClip(getChildAt(i)).mouseChildren = false; 
} 
//reuse this array 
var clips:Array; 
addEventListener(Event.ENTER_FRAME, checkClickables); 
function checkClickables(event:Event):void { 
    clips = this.getObjectsUnderPoint(new Point(mouseX,mouseY)); 
    for(i = 0 ; i < clips.length ; i++){ 
     if(isInteractiveObject(clips[i])){ 
      trace(clips[i]); 
     } 
    } 
} 
function isInteractiveObject(object:*):Boolean{ 
    var extendsClass:XMLList = describeType(object).extendsClass; 
    for each(var classDef:XML in extendsClass){ 
     if([email protected] == 'flash.display::InteractiveObject') return true; 
    } 
    return false; 
} 

我在舞台上的一些片段,我正在做一些他们的“点击”。 的onEnterFrame然后我检查是否有InteractiveObject的子类 (超类的任何东西可点击)

的任何实例出于某种原因,在我的测试,getObjectsUnderPoint()只返回形状对象,没有精灵。 也许它可能在你的配置中工作。

此外它似乎有点复杂。

这里是我的第二个方法:

function getInteractiveObjects(container:DisplayObjectContainer):Array{ 
    var result:Array = []; 
    for(var i:int = 0 ; i < container.numChildren ; i++){ 
     if(container.getChildAt(i) is Sprite || container.getChildAt(i) is MovieClip) result.push(container.getChildAt(i)); 
     if(container.getChildAt(i) is DisplayObjectContainer){ 
      var clips:Array = getInteractiveObjects(DisplayObjectContainer(container.getChildAt(i))); 
      var clipsNum:int = clips.length; 
      for(var j:int = 0 ; j < clipsNum ; j++) 
       if(clips[j] is Sprite || clips[j] is MovieClip) result.push(clips[j]) 
     } 
    } 
    return result; 
} 

使用递归函数获取潜在目标的交互剪辑一个内部(如加载的内容)。如果它是Sprite或MovieClip,它是'可点击的'。

var iclips:Array = getInteractiveObjects(this); 
for(i = 0 ; i < iclips.length ; i++){ 
    trace(iclips[i].name); 
    //do extra tests here 
    if(iclips[i].hasEventListener(MouseEvent.ROLL_OVER)) trace(iclips[i].name + ' has roll over'); 
    //etc. 
} 

那么你可以做额外的测试,这取决于正是你要寻找的(无论它有和事件侦听器的鼠标事件,要么是将mouseEnabled,具有buttonMode设置为true,等等)

这样你就不需要检查任何鼠标了(不必等待用户交互或者始终调用一个函数),一旦你得到的剪辑不符合你的想法,你可以改变他们的行为(mouseChildren = false,或其他)。

HTH