Click to hit underneath

2019-08-05 20:05发布

I have a UIComponent that sits on top of a grid visually, which is also a UIComponent. The grid and the UIComponent that sits on top are on different branches. The gird has children which are Sprites. When the MousEvent.CLICK is dispatched it goes to the UIComponent on top. What I want it to do is go the element of the grid underneath. Is this possible?

3条回答
贼婆χ
2楼-- · 2019-08-05 20:39

Yes you can,

if your element id is "ui_component"

then in ActionScript you should add two properties

ui_component.mouseEnabled = true;
ui_component.mouseChildren = true;

This will tell your component to pass click event on MovieClip behind it.

I hope this helps.

查看更多
男人必须洒脱
3楼-- · 2019-08-05 20:39

Another option, if your implementation does not allow for you to disable the mouse events for the top UIComponent, is to manually redispatch the event.

Here's a rather generic example. Attach the following handler for a MouseEvent.CLICK to either the container that holds the other UIComponents or the one on the UIComponent on top:

private function propagateClickEvent(event:MouseEvent):void
{
    // find all objects under the click location
    var uicOver:Array = getObjectsUnderPoint(new Point(event.stageX, event.stageY));

    // filter out what you don't want; in this case, I'm keeping only UIComponents
    uicOver = uicOver.filter(isUIComponent);

    // resolve skins to parent components
    uicOver = uicOver.map(resolveSkinsToParents);

    // remove the current item (otherwise this function will exec twice)
    if (event.currentTarget != event.target) { // otherwise let the following line do the removal
        uicOver.splice(uicOver.indexOf(event.currentTarget),1);
    }

    // remove the dispatching item (don't want to click it twice)
    uicOver.splice(uicOver.indexOf(event.target),1);

    // dispatch a click for everything else
    for each (var uic:UIComponent in uicOver) {
        uic.dispatchEvent(new MouseEvent(MouseEvent.CLICK, false)); // no bubbling! 
    }
}

// test if array item is a UIComponent
private function isUIComponent(item:*, index:int, arr:Array):Boolean {
    return item is UIComponent;
}

// resolve Skins to parent components
private function resolveSkinsToParents(item:*, index:int, arr:Array):* {
    if (item is Skin) {
         return item.parent;
    }
    return item;
}

This code would work as follows in MXML:

<s:Group click="propagateClickEvent(event)">
    <s:Button click="trace('button1')"/>
    <s:Button click="trace('button2')"/>
    <s:Button click="trace('button3')"/>
</s:Group>

<!-- trace output on click: "button3", "button1", "button2" -->

This is very generic. I'd recommend using something more specific than UIComponent, otherwise it would probably dispatch more clicks than are necessary. That all depends on what you're actually doing.

Also, the MXML example is rather poor, since, if you knew all your components beforehand you could definitely handle it differently. However, if you had a bunch of components whose positions were determined at runtime, this would approach would make more sense.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-08-05 20:43

What I had to do was just make the UIComponent on top top.mousEnabled = false

查看更多
登录 后发表回答