我正在构建一个加载外部SWF的专用查看器应用程序。
var content:Sprite = ...
content.addChild(loader);
我会收听我的顶级内容Sprite MOUSE_OVER和MOUSE_OUT事件。 over处理程序隐藏默认光标并显示自定义(缩放)光标。 Out处理程序将光标更改回默认值。
我想要实现的是当鼠标悬停在外部加载的SWF中的可点击项目(如按钮或文本链接)上时,不显示缩放光标。
当前代码适用于AVM1 swfs。 问题在于使用AS3加载的swfs。 对于这些内容,MOUSE_OUT被触发并且立即触发MOUSE_OVER,因此光标仍然是错误的。
这可能归结为:如何检查鼠标是否在内容的可点击子项上?
答案 0 :(得分: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(classDef.@type == 'flash.display::InteractiveObject') return true;
}
return false;
}
我在舞台上有一些片段,我正在制作一些“可点击”的片段。 然后onEnterFrame我正在检查是否有子类的任何实例 InteractiveObject(任何可点击的超类)
出于某种原因,在我的测试中,getObjectsUnderPoint()只返回Shape对象,没有Sprite。 也许它可能适用于您的配置。
这似乎有点复杂。
这是我的第二种方法:
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
答案 1 :(得分:0)
通过一些测试以及George给我的提示,这是我刚刚写的内容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
检查。
除非有人知道检测鼠标在文本字段链接上的技巧吗?