Actionscript:for..in 循环的输出在 Flash IDE 和浏览器中的显示之间发生变化

Posted

技术标签:

【中文标题】Actionscript:for..in 循环的输出在 Flash IDE 和浏览器中的显示之间发生变化【英文标题】:Actionscript: Output of for..in loop changes between Flash IDE and display in browser 【发布时间】:2018-05-03 04:55:28 【问题描述】:

我正在使用 GraphicElements 和 TextElements 在 AS3 中构建显示文本和图形组合的菜单。从 Flash IDE 发布时,菜单按预期显示(示例 1),但在浏览器的 Flash 播放器中显示时,它们的内容以完全不同的顺序显示(现阶段为 FF 和 IE)。 IDE 正在发布到 Flash 播放器 25,但内容的错误排序发生在从 11.x 到 27.x 的 Flash 播放器版本中

代码如下:

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:

有人可以建议我做错了什么以及如何解决它吗?

【问题讨论】:

这是预期的行为。可悲的是,对象是这样枚举的,无法预测 for..in 枚举的顺序或依赖它。您需要在没有 for..in 循环的情况下按所需顺序对结果进行排序或测试这些属性。 您可以在之前构建图形对象(作为渲染),因此将值(来自您的数组)放入其中 【参考方案1】:

试试这个,而不是你的外部 for in 循环。

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);
                                                               
                
            

至于您的内部for in 循环,我们需要更多地了解obj.data 是什么。是object吗?它可以有多少属性?如果它的属性需要按特定顺序读取,那么它应该是Array 而不是object。如果没有,您仍然可以使用for each in 而不是for in 来简化您的代码。

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

【讨论】:

好方法凯尔,谢谢。我最终将代码更改为使用数组,因为在这种情况下特定的顺序很重要。

以上是关于Actionscript:for..in 循环的输出在 Flash IDE 和浏览器中的显示之间发生变化的主要内容,如果未能解决你的问题,请参考以下文章

详解 for in 循环方法

for循环,for...in循环,forEach循环的区别

for in循环介绍以及陷阱

JavaScript-//FOR/IN循环。当使用for/in循环遍历关联数组时,就可以清晰地体会到for/in的强大之处。

for循环,for…in循环,forEach循环的区别

for-in和for 循环 的区别