swf中的冒泡点击事件

时间:2012-11-15 17:26:54

标签: actionscript-3 flash event-handling

我尝试将一个MovieClip动态添加到现有的SWF中 - 注入一个代码如下的小代码:

this.obj = new MovieClip(); // it is inside an object
obj.name = 'FLOOR';
obj.graphics.beginFill(0xFFFFFF, 0);
obj.graphics.drawRect(0,0,self.width, self.height);
obj.graphics.endFill();
obj.buttonMode = true;
self.addChildAt( floorLayerMC , 0); /* self is an reference for the this keyword, reference for the entire swf */

我的问题是:这个SWF有很多元素,比如图像和文本字段,其中一些元素没有用于点击的事件处理程序。我需要找到一种方法将所有事件“重定向”到我的“FLOOR”元素,使用类似于冒泡的事件。

当然,我可以在任何元素的顶部添加FLOOR但是我有一些带有click处理程序的元素。我不能忽视所有的元素。所以我的问题是:

如果我点击带有点击处理程序的MovieClip,请执行原始操作。 如果我点击没有点击处理程序的MovieClip,请执行FLOOR操作。

我无法在所有元素中添加事件处理程序。

任何想法?

1 个答案:

答案 0 :(得分:0)

听取容器movieclip自己的舞台(包含FLOOR的动画片段)的点击。在click事件的handler方法中,使用hitTestPoint和容器movieclip的mouseX和MouseY进行命中测试,如果鼠标位于任何可点击的对象之上,则忽略阶段点击。存储可在数组中单击的所有对象以进行该测试。

此代码未经测试,但它会是这样的:

var exemptArray:Array = [ btn_mc1, btn_mc2, btn_mc3 ];
containerMC.stage.addEventListener(MouseEvent.CLICK, onClickMyMC);

function onClickMyMC( event:Event ):void
{
    for(var i:int = 0; i < exemptArray.length; i++)
    {
        if( exemptArray[i].hitTestPoint(containerMC.mouseX, containerMC.mouseY) )
        {
            // do nothing, ignore the stage click ( and let the object with the click respond )
            break;
        }
        else
        {
            // respond to the stage click
        }
    }
}

要在不知道哪些对象可提前点击的情况下构建exemptArray: (未经测试,但应该足够接近,以便给你一个想法)。

var exemptArray:Array = buildExemptArray();

function buildExemptArray():Array
{
    var arr:Array = [];

    for(var j:int = 0; j < containerMC.numChildren; j++)
    {
        if( containerMC.getChildAt(i).hasEventListener(MouseEvent.CLICK) )
        {
            arr.push( containerMC.getChildAt(i) );
        }
    }

     return arr:
}

编辑评论中的答案:

this.addEventListener(MouseEvent.CLICK,onClick)会向整个对象添加点击事件,包含儿童

this.stage.addEventListener(MouseEvent.CLICK,onClick)只会在动画片段的舞台上添加一个点击,不是它的孩子

在as3中,所有的动画片段都有舞台属性。如果您在主时间轴上写了 this.stage.addEventListener(MouseEvent.CLICK,onClick); ,则会在整个swf中添加一个阶段点击。但是,如果您写了类似 myMC.stage.addEventListener(MouseEvent.CLICK,onClick); 的内容,它只会向该movieclip的舞台(myMC的舞台)添加一个点击。由于stage位于显示列表下方,因此您可以在任何动画片段中捕获其中的单击。如果您无法提前访问所有具有鼠标事件的对象,则可以循环遍历所有容器的子项,并检查它们是否具有带 .hasEventListener(MouseEvent.CLICK)的mouseEvent; ,从中创建你的exemptArray,然后使用上面相同的逻辑来忽略exemptArray中的项目。