Search code examples
actionscript-3actionscript

Actionscript: Output of for..in loop changes between Flash IDE and display in browser


I am using GraphicElements and TextElements to build menus in AS3 that display a combination of text and graphics. The menus appear as expected (example 1) when published from the Flash IDE, but their content appears in a completely different order when displayed in the Flash player in a browser (FF and IE at this stage). The IDE is publishing to Flash player 25, but the mis-ordering of content happens in Flash player versions from 11.x up to 27.x

Here is the code:

private function buildMenu(obj:Object,rev:Boolean):Object {
//trace ('here is the title: '+obj.title);          
var groupVector:Vector.<ContentElement> = new Vector.<ContentElement>(); 

for (var i in obj)
{
    if (obj[i] != null)
    {
        //trace ('as a string: '+String(i));
        switch(String(i))
        {
            case "icon" :
                //trace ('you found an icon: '+obj[i]); 
                var graphicElement:GraphicElement = new GraphicElement(obj[i],obj[i].width,obj[i].height/2,obj.tCol);
                groupVector.unshift(graphicElement);
                break;
            case "title" :
                //trace ('you found a title');
                var textElement:TextElement = new TextElement(obj.title, obj.tCol); 
                groupVector.push(textElement);
                break;
            case "data" :
                //trace ('you found data');
                for (var y in obj[i])
                {
                    var tmpitem = obj[i][y];
                    //trace ('typeof y: '+typeof(tmpitem));
                    if (tmpitem!= null)
                    {
                        if (typeof(tmpitem) == "object")
                        {
                            //trace ('y is a graphic: '+tmpitem+'......'+tmpitem.width);
                            var graphicElement:GraphicElement = new GraphicElement(tmpitem,tmpitem.width,tmpitem.height/2,obj.tCol);
                            groupVector.push(graphicElement);   
                        } else 
                        {
                            //trace ('y is text: '+tmpitem);
                            var textElement:TextElement = new TextElement(tmpitem, obj.dataCol); 
                            groupVector.push(textElement);
                        }                                           
                    }
                }
                break;

            default:
                break;          
        }
    }
}
if (rev) //turns the entry around to list from the right
{
    groupVector.reverse();
}

//working lines
var groupElement = new GroupElement(groupVector); 
var textBlock:TextBlock = new TextBlock();
textBlock.content = groupElement; 
var textLine:TextLine = textBlock.createTextLine(null, 400);
return textLine;
}

Here is the expected output (published within the Flash IDE):

And here is the same published swf displayed in a browser:

Can someone suggest what I'm doing wrong and how to fix it please?


Solution

  • Try this instead of your outer for in loop.

    if (obj.icon)
    {
                //trace ('you found an icon: '+obj[i]); 
                var graphicElement:GraphicElement = new GraphicElement(obj[i],obj[i].width,obj[i].height/2,obj.tCol);
                groupVector.unshift(graphicElement);
    }
    
    if (obj.title)
    {
                //trace ('you found a title');
                var textElement:TextElement = new TextElement(obj.title, obj.tCol); 
                groupVector.push(textElement);
    }
    
    if (obj.data)
    {
                //trace ('you found data');
                for (var y in obj.data)
                {
                    var tmpitem = obj.data[y];
                    //trace ('typeof y: '+typeof(tmpitem));
                    if (tmpitem!= null)
                    {
                        if (typeof(tmpitem) == "object")
                        {
                            //trace ('y is a graphic: '+tmpitem+'......'+tmpitem.width);
                            var graphicElement:GraphicElement = new GraphicElement(tmpitem,tmpitem.width,tmpitem.height/2,obj.tCol);
                            groupVector.push(graphicElement);   
                        } else 
                        {
                            //trace ('y is text: '+tmpitem);
                            var textElement:TextElement = new TextElement(tmpitem, obj.dataCol); 
                            groupVector.push(textElement);
                        }                                           
                    }
                }
    }
    

    As for your inner for in loop, we'll need to know more about what obj.data is. Is it an object? How many properties could it have? If its properties need to be read in a specific order then it should be an Array instead of an object. If not, you can still simplify your code by using for each in instead of for in.

                for each (var tmpitem in obj.data)
                {
                    // No need for var tmpitem = obj.data[y];