Flex 4 在鼠标悬停时显示交互式容器

发布于 2024-10-01 00:04:57 字数 950 浏览 4 评论 0原文

目前我正在尝试创建一个位于另一个容器 A 内的容器 B。 容器 B 默认情况下是不可见的,当进入容器 A 时,它应该变得可见并且可以交互。 (将容器 B 想象为一个按钮)

我使用以下代码

<fx:Script>
    <![CDATA[
        protected function mouseOverHandler(event:MouseEvent):void
        {
            this.voter.conB = true;
            this.voter.conB = true;
            this.addElement(this.conB);
        }

        protected function mouseOutHandler(event:MouseEvent):void
        {
            this.conB.visible = false;
            this.conB.enabled = false;
            this.addElement(this.conA);
        }
    ]]>
</fx:Script>

    <s:element id="conB" visible="false"/>
    <s:element id="conA" mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)"/>

基本上它的工作原理,我遇到的问题是,当我滚动容器 B 时,flex 将其计为容器 A 中的 mouseOutEvent,这使得容器 B 再次不可见,而不是再次鼠标位于容器 A 上,因为 B 不可见,并且 B 再次被触发可见。 结果是容器 b 上出现闪烁效果,这也导致无法单击容器 b 内的按钮。

有什么想法可以解决这个问题/以另一种方式实现我的意图吗?

Currently i'm trying to create a container B which is within another container A.
Container B is invisible by default, when entering container A it is supposed to turn visible and be interactive. (imagine container B as a button)

i'm using the following code

<fx:Script>
    <![CDATA[
        protected function mouseOverHandler(event:MouseEvent):void
        {
            this.voter.conB = true;
            this.voter.conB = true;
            this.addElement(this.conB);
        }

        protected function mouseOutHandler(event:MouseEvent):void
        {
            this.conB.visible = false;
            this.conB.enabled = false;
            this.addElement(this.conA);
        }
    ]]>
</fx:Script>

    <s:element id="conB" visible="false"/>
    <s:element id="conA" mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)"/>

Basicly its working, the problem that i have is that when i roll over containerB then flex counts that as mouseOutEvent from container A, which makes containerB invisible again, than again the mouse is on container A since B is invisible and B again gets triggered visible.
the result is a flicker effect on container b, which also makes it impossible to click the button within container b.

any ideas how to solve that problem / another way to realize what i intend?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绳情 2024-10-08 00:04:57

嗯,不,这不是问题。

代码如下:

基本上,我使用 Spark 按钮类的自定义皮肤(此处名为“测试”)对其进行了测试,这里是它的样子,但就像我说的,它是未编辑纯自动- 为 Spark 按钮类定义新皮肤时生成的 Flex 代码

    <?xml version="1.0" encoding="utf-8"?>

<!--

    ADOBE SYSTEMS INCORPORATED
    Copyright 2008 Adobe Systems Incorporated
    All Rights Reserved.

    NOTICE: Adobe permits you to use, modify, and distribute this file
    in accordance with the terms of the license agreement accompanying it.

-->

<!--- The default skin class for the Spark Button component.  

       @see spark.components.Button

      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="21" minHeight="21" alpha.disabled="0.5">

    <!-- host component -->
    <fx:Metadata>
        <![CDATA[ 
        /** 
         * @copy spark.skins.spark.ApplicationSkin#hostComponent
         */
        [HostComponent("spark.components.Button")]
        ]]>
    </fx:Metadata>

    <fx:Script fb:purpose="styling">
        <![CDATA[         
            /* Define the skin elements that should not be colorized. 
            For button, the graphics are colorized but the label is not. */
            static private const exclusions:Array = ["labelDisplay"];

            /** 
             * @private
             */     
            override public function get colorizeExclusions():Array {return exclusions;}

            /**
             * @private
             */
            override protected function initializationComplete():void
            {
                useChromeColor = true;
                super.initializationComplete();
            }  

            /**
             *  @private
             */
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
            {
                var cr:Number = getStyle("cornerRadius");

                if (cornerRadius != cr)
                {
                    cornerRadius = cr;
                    shadow.radiusX = cornerRadius;
                    fill.radiusX = cornerRadius;
                    lowlight.radiusX = cornerRadius;
                    highlight.radiusX = cornerRadius;
                    border.radiusX = cornerRadius;
                }

                if (highlightStroke) highlightStroke.radiusX = cornerRadius;
                if (hldownstroke1) hldownstroke1.radiusX = cornerRadius;
                if (hldownstroke2) hldownstroke2.radiusX = cornerRadius;

                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }

            private var cornerRadius:Number = 2;
        ]]>        
    </fx:Script>

    <!-- states -->
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: shadow -->
    <!--- @private -->
    <s:Rect id="shadow" left="-1" right="-1" top="-1" bottom="-1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0x000000" 
                                 color.down="0xFFFFFF"
                                 alpha="0.01"
                                 alpha.down="0" />
                <s:GradientEntry color="0x000000" 
                                 color.down="0xFFFFFF" 
                                 alpha="0.07"
                                 alpha.down="0.5" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 2: fill -->
    <!--- @private -->
    <s:Rect id="fill" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF" 
                                 color.over="0xBBBDBD" 
                                 color.down="0xAAAAAA" 
                                 alpha="0.85" />
                <s:GradientEntry color="0xD8D8D8" 
                                 color.over="0x9FA0A1" 
                                 color.down="0x929496" 
                                 alpha="0.85" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 3: fill lowlight -->
    <!--- @private -->
    <s:Rect id="lowlight" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="270">
                <s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" />
                <s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" />
                <s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 4: fill highlight -->
    <!--- @private -->
    <s:Rect id="highlight" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.0"
                                 alpha="0.33" 
                                 alpha.over="0.22" 
                                 alpha.down="0.12"/>
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.48"
                                 alpha="0.33"
                                 alpha.over="0.22"
                                 alpha.down="0.12" />
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.48001"
                                 alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 5: highlight stroke (all states except down) -->
    <!--- @private -->
    <s:Rect id="highlightStroke" left="1" right="1" top="1" bottom="1" radiusX="2" excludeFrom="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0xFFFFFF" alpha.over="0.22" />
                <s:GradientEntry color="0xD8D8D8" alpha.over="0.22" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 6: highlight stroke (down state only) -->
    <!--- @private -->
    <s:Rect id="hldownstroke1" left="1" right="1" top="1" bottom="1" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.001" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.0011" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.965" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.9651" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
    <!--- @private -->
    <s:Rect id="hldownstroke2" left="2" right="2" top="2" bottom="2" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.09" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.0001" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 7: border - put on top of the fill so it doesn't disappear when scale is less than 1 -->
    <!--- @private -->
    <s:Rect id="border" left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" 
                                 alpha="0.5625"
                                 alpha.down="0.6375" />
                <s:GradientEntry color="0x000000" 
                                 alpha="0.75" 
                                 alpha.down="0.85" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 8: text -->
    <!--- @copy spark.components.supportClasses.ButtonBase#labelDisplay -->
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="middle"
             maxDisplayedLines="1"
             horizontalCenter="0" verticalCenter="1"
             left="10" right="10" top="2" bottom="2">
    </s:Label>

</s:SparkSkin>

接下来,我们将自定义组件命名为“容器”

    <?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="components.*"
             width="200" height="100">

    <s:TextArea id="text_box" width="100%" height="100%">

    </s:TextArea>
    <s:HGroup id="my_container" gap="20" width="100" height="40" verticalCenter="0" horizontalCenter="0">
        <components:test/>
            <s:button />
    </s:HGroup>
</s:Group>

,最后我们将其放入主应用程序中,例如:

    <?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" height="100" width="200" xmlns:components="components.*" backgroundAlpha="0">
    <fx:Declarations>

    </fx:Declarations>

    <fx:Script>
        <![CDATA[



            protected function mouseOverHandler(event:MouseEvent):void
            {
                this.myObject.my_container.visible = true;
                this.myObject.my_container.enabled = true;
            }

            protected function mouseOutHandler(event:MouseEvent):void
            {
                this.myObject.my_container.visible = false;
                this.myObject.my_container.enabled = false;
            }
        ]]>
    </fx:Script>

        <components:Comment id="myObject" mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)">

        </components:Comment>

</s:Application>

现在,如果您尝试这样做,您将看到自定义 Spark此容器内的按钮组件不可单击。然而,标准的 s:button 组件是可点击的,我不知道为什么。

Hmm no thats not the problem.

here what the code looks like:

basicly i tested it with a custom skin (here named "test") for the spark button class, here what it looks like, but like i said its the unedited pure auto-generated flex code when defining a new skin for the spark button class

    <?xml version="1.0" encoding="utf-8"?>

<!--

    ADOBE SYSTEMS INCORPORATED
    Copyright 2008 Adobe Systems Incorporated
    All Rights Reserved.

    NOTICE: Adobe permits you to use, modify, and distribute this file
    in accordance with the terms of the license agreement accompanying it.

-->

<!--- The default skin class for the Spark Button component.  

       @see spark.components.Button

      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="21" minHeight="21" alpha.disabled="0.5">

    <!-- host component -->
    <fx:Metadata>
        <![CDATA[ 
        /** 
         * @copy spark.skins.spark.ApplicationSkin#hostComponent
         */
        [HostComponent("spark.components.Button")]
        ]]>
    </fx:Metadata>

    <fx:Script fb:purpose="styling">
        <![CDATA[         
            /* Define the skin elements that should not be colorized. 
            For button, the graphics are colorized but the label is not. */
            static private const exclusions:Array = ["labelDisplay"];

            /** 
             * @private
             */     
            override public function get colorizeExclusions():Array {return exclusions;}

            /**
             * @private
             */
            override protected function initializationComplete():void
            {
                useChromeColor = true;
                super.initializationComplete();
            }  

            /**
             *  @private
             */
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
            {
                var cr:Number = getStyle("cornerRadius");

                if (cornerRadius != cr)
                {
                    cornerRadius = cr;
                    shadow.radiusX = cornerRadius;
                    fill.radiusX = cornerRadius;
                    lowlight.radiusX = cornerRadius;
                    highlight.radiusX = cornerRadius;
                    border.radiusX = cornerRadius;
                }

                if (highlightStroke) highlightStroke.radiusX = cornerRadius;
                if (hldownstroke1) hldownstroke1.radiusX = cornerRadius;
                if (hldownstroke2) hldownstroke2.radiusX = cornerRadius;

                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }

            private var cornerRadius:Number = 2;
        ]]>        
    </fx:Script>

    <!-- states -->
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: shadow -->
    <!--- @private -->
    <s:Rect id="shadow" left="-1" right="-1" top="-1" bottom="-1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0x000000" 
                                 color.down="0xFFFFFF"
                                 alpha="0.01"
                                 alpha.down="0" />
                <s:GradientEntry color="0x000000" 
                                 color.down="0xFFFFFF" 
                                 alpha="0.07"
                                 alpha.down="0.5" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 2: fill -->
    <!--- @private -->
    <s:Rect id="fill" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF" 
                                 color.over="0xBBBDBD" 
                                 color.down="0xAAAAAA" 
                                 alpha="0.85" />
                <s:GradientEntry color="0xD8D8D8" 
                                 color.over="0x9FA0A1" 
                                 color.down="0x929496" 
                                 alpha="0.85" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 3: fill lowlight -->
    <!--- @private -->
    <s:Rect id="lowlight" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="270">
                <s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" />
                <s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" />
                <s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 4: fill highlight -->
    <!--- @private -->
    <s:Rect id="highlight" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.0"
                                 alpha="0.33" 
                                 alpha.over="0.22" 
                                 alpha.down="0.12"/>
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.48"
                                 alpha="0.33"
                                 alpha.over="0.22"
                                 alpha.down="0.12" />
                <s:GradientEntry color="0xFFFFFF"
                                 ratio="0.48001"
                                 alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- layer 5: highlight stroke (all states except down) -->
    <!--- @private -->
    <s:Rect id="highlightStroke" left="1" right="1" top="1" bottom="1" radiusX="2" excludeFrom="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0xFFFFFF" alpha.over="0.22" />
                <s:GradientEntry color="0xD8D8D8" alpha.over="0.22" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 6: highlight stroke (down state only) -->
    <!--- @private -->
    <s:Rect id="hldownstroke1" left="1" right="1" top="1" bottom="1" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.001" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.0011" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.965" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.9651" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
    <!--- @private -->
    <s:Rect id="hldownstroke2" left="2" right="2" top="2" bottom="2" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.09" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.0001" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 7: border - put on top of the fill so it doesn't disappear when scale is less than 1 -->
    <!--- @private -->
    <s:Rect id="border" left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" 
                                 alpha="0.5625"
                                 alpha.down="0.6375" />
                <s:GradientEntry color="0x000000" 
                                 alpha="0.75" 
                                 alpha.down="0.85" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>

    <!-- layer 8: text -->
    <!--- @copy spark.components.supportClasses.ButtonBase#labelDisplay -->
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="middle"
             maxDisplayedLines="1"
             horizontalCenter="0" verticalCenter="1"
             left="10" right="10" top="2" bottom="2">
    </s:Label>

</s:SparkSkin>

next we have our custom component named "container" like

    <?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="components.*"
             width="200" height="100">

    <s:TextArea id="text_box" width="100%" height="100%">

    </s:TextArea>
    <s:HGroup id="my_container" gap="20" width="100" height="40" verticalCenter="0" horizontalCenter="0">
        <components:test/>
            <s:button />
    </s:HGroup>
</s:Group>

and finaly we put that into the main application like:

    <?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" height="100" width="200" xmlns:components="components.*" backgroundAlpha="0">
    <fx:Declarations>

    </fx:Declarations>

    <fx:Script>
        <![CDATA[



            protected function mouseOverHandler(event:MouseEvent):void
            {
                this.myObject.my_container.visible = true;
                this.myObject.my_container.enabled = true;
            }

            protected function mouseOutHandler(event:MouseEvent):void
            {
                this.myObject.my_container.visible = false;
                this.myObject.my_container.enabled = false;
            }
        ]]>
    </fx:Script>

        <components:Comment id="myObject" mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)">

        </components:Comment>

</s:Application>

now if you try that, you'll see that the custom spark button component within this container is not clickable. however, the standard s:button component IS clickable, and i dunno why.

薆情海 2024-10-08 00:04:57

如果 conB 是 conA 的子级,那么我认为将鼠标悬停在 conB 上不会触发 conA 上的鼠标移出。相同的基本事件逻辑应该仍然有效......

If conB is a child of conA, then I would think mousing over conB would not trigger a mouseout on conA. The same basic event logic should still work...

冷情 2024-10-08 00:04:57

好吧,我不完全确定我理解您的场景...查看代码可能会有所帮助,但我知道如果您在某个元素上有皮肤并且您希望该元素包含另一个元素,则皮肤需要具有以下

<s:Group id="contentGroup" depth="25"> 
  <s:layout> 
    <s:BasicLayout/>
  </s:layout> 
</s:Group> 

内容 : contentGroup 是一个神奇的 ID,让皮肤知道嵌套在皮肤对象中的所有内容(换句话说,皮肤所应用的对象)都没有被皮肤本身覆盖。深度是 z-index,“contentGroup”组的深度需要高于皮肤中其他任何内容。希望这有帮助。

Well I'm not totally sure I understand your scenario...seeing the code would probably help, but I know if you have a skin on an element and you want that element to contain another element, the skin needs to have this:

<s:Group id="contentGroup" depth="25"> 
  <s:layout> 
    <s:BasicLayout/>
  </s:layout> 
</s:Group> 

The contentGroup is something of a magic ID for skins to know that everything you nest in the skin's object (in other words, what the skin is being applied to) is not covered by the skin itself. Depth is the z-index, and the depth of the "contentGroup" group needs to be higher than anything else in the skin. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文