【问题标题】:Bubble click event in swfswf 中的气泡点击事件
【发布时间】:2012-11-15 17:26:53
【问题描述】:

我尝试将一个 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,但我有一些带有点击处理程序的元素。我不能忽略所有的元素。所以我的问题是:

如果我使用单击处理程序单击一个影片剪辑,则执行原始操作。 如果我在没有单击处理程序的情况下单击 MovieClip,请执行 FLOOR 操作。

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

有什么想法吗?

【问题讨论】:

  • 您可以访问 SWF 源吗?
  • 当然可以,但我无法更改或破坏某些现有行为(例如某些动画)。
  • 您可以做的是,将您现有的 SWF 中的点击侦听器更改为使用捕获阶段(或以更高的优先级进行侦听),然后在它们执行完操作后停止传播。然后在您的容器/主应用程序中,侦听通常的冒泡阶段(或以较低的优先级)。然后,如果该事件的侦听器已经存在,它将在处理时被取消,并且您更广泛的侦听器将不会运行

标签: actionscript-3 flash event-handling


【解决方案1】:

监听对容器影片剪辑自己的舞台(包含 FLOOR 的影片剪辑)的点击。在单击事件的处理程序方法中,使用 hitTestPoint 和容器动画剪辑的 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
        }
    }
}

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

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 中,所有的movieclip 都有一个stage 属性。如果您在主时间轴上写 this.stage.addEventListener(MouseEvent.CLICK, onClick); 这将添加一个舞台点击到整个 swf。但是,如果您编写类似 myMC.stage.addEventListener(MouseEvent.CLICK, onClick); 之类的内容,它只会向该影片剪辑的舞台(myMC 的舞台)添加一次点击。由于舞台位于显示列表下方,因此您可以在任何影片剪辑中捕捉点击。如果您无法提前访问所有具有鼠标事件的对象,则可以循环遍历所有容器的子对象,并使用 .hasEventListener(MouseEvent.CLICK); 检查它们是否具有 mouseEvent ,从中创建您的 excludeArray,然后使用上述相同的逻辑来忽略 excludeArray 中的项目。

【讨论】:

  • 哇...这是个好主意,但我无法控制影片剪辑列表。我正在考虑以更干净的方式使用 onClickMyMC,作为我的 FLOOR,并在我可以控制的所有影片剪辑中添加一个 event.stopPropagation(),并推广关于在任何影片剪辑中添加类似代码的规则。有什么区别:
  • this.addEventListener 和 this.stage.addEventListener ? (这代表整个 swf)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
相关资源
最近更新 更多