2

我认为这是我在 jQuery 和 javascript 中遇到的另一个技巧变量范围和 ajax 问题。

假设我有一个对象:

Container = function()
{
//CSS Style Paramaters:
    this.width = "";
    this.height = "";
    this.margin = "";
    this.margin_option = "";
    this.position = ""; 
}

我有这个对象的一个​​方法,它应该从一个 xml 文件中读取一些 xml 数据并将它们存储到这个对象的成员中:

Container.prototype.readXML4Container =function()
{
            var self = this;
        $.get("assest/xml/layout.xml",function(xml)
        {
                  $(xml).find("body").each(function(){
                     self.width = ($(this).find("width").text());
                     self.height = ($(this).find("height").text());
                     self.margin = ($(this).find("margin").text());
                     //And more code like this.
        });
       });
}

在这个函数之后,还有另一个函数需要调用它,并使用 .css() 应用 CSS 数据

Container.prototype.applyCSS = function()
{
    this.readXML4Container();

    $("#container").css({
        'width':this.width,
        'height':this.height,
        'position':this.position,
        'margin': this.margin
    });

}       

XML 文件如下所示:

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

<root>
<body>
    <margin>0</margin>
    <padding>0</padding>
    <font-family>Trebuchet MS, sans-serif</font-family>
    <color>#666</color>
</body> 
<container>
    <width>1220px</width>
    <height>730px</height>
    <margin>0 auto</margin>
    <position>relative</position>
    <font-size>1.0em</font-size>
    <font-color>blue</font-color>
</container>


<Menubar>
    <width>660px</width>
    <height>58px</height>
    <position>absolute</position>
    <left>275px</left>  
</Menubar>

<Mainsection>
    <width>664px</width>
    <height>660px</height>
    <position>absolute</position>
    <position-left>270px</position-left>
    <position-top>60px</position-top>   
</Mainsection>
</root>

我的问题是,该值似乎从未存储到成员变量中。当我创建该对象的实例并调用这两个函数时,CSS 样式永远不会应用于 HTML 中的 DOM。

但是,如果我不读取 XML 文件而只是在开始时给出一些值,它就可以正常工作。所以我知道我的 applyCSS 部分应该不错。问题应该在读取和存储阶段。

我试图解决这个问题超过一天......有人可以帮我解决这个问题吗?谢谢!

4

2 回答 2

1

好吧,走着瞧。你有大约3个问题。

1) self.margin = ($(this).find("margin).text());

您缺少围绕边距的结束双引号

2) 您的 XML 无效:<position-left>275px</left>

3) 最后一点:记住,您使用的是 AJAX。不要忘记 A 代表什么:)。您的函数执行此操作:

    this.readXML4Container();

        $("#container").css({
            'width':this.width,
            'height':this.height,
            'position':this.position,
            'margin': this.margin
        });

But readXML4Container is ASYNCHRONOUS. So you call your readXML method and then immediately try to apply the CSS, but the css hasn't been loaded yet from the server. 

你真的应该只有一个这样的功能:

 Container.prototype.readXML4Container =function()
        {
            var self = this;
            $.get("XMLFile1.xml",function(xml)
            {                
                $(xml).find("body").each(function () {

                    self.width = ($(this).find("width").text());
                    self.height = ($(this).find("height").text());
                    self.margin = ($(this).find("margin").text());
                });

                $("#container").css({
                    'width': self.width,
                    'height': self.height,
                    'position': self.position
                });
            });
        }

当然,你还有其他问题,比如为什么你有两个 body 标签?只有最后一个适用。然后,当然,您的正文 XML 甚至没有“具有”宽度和高度的属性......

于 2012-08-30T21:55:08.920 回答
0

我遇到过这个问题几次。我通常在设计 Javascript 类时略有不同,并且从未遇到过这种方法的范围问题。

下面的示例可以满足您的需求(使用一些虚拟数据,在虚拟 Ajax 请求和循环中满足范围问题)。它还创建了两个带有随机数据的对象,以测试它们是否没有静态存储在原型中。超时是为了保证Ajax请求在输出数据之前已经完成。http://jsfiddle.net/wERTp/16/

var Container = function()
{
};

Container.prototype = {    
    width: '',
    height: '',
    margin: '',
    margin_option: '',
    position: '',

    readXML4Container: function()
    {
        $.get("", this.saveValues.bind(this));
    },

    saveValues: function(xml) {
        var self = this;
        var values = [{
            width: 10 + Math.random(),
            height: 10 + Math.random(),
            margin: 10 + Math.random(),
            margin_option: '',
            position: 'relative'
        }];
        $.each(values, function() {
            self.width = this.width;
            self.height = this.height;
            self.margin = this.margin;
            self.margin_option = this.margin_option;
            self.position = this.position;
        });
    },

    outputValues: function() {
        console.log(this.width, this.height, this.margin, this.margin_option, this.position);
    }
}

var container = new Container();
container.readXML4Container();
setTimeout(function() {
    container.outputValues();
}, 1000);

var container2 = new Container();
container2.readXML4Container();
setTimeout(function() {
    container2.outputValues();
}, 1000);​
于 2012-08-30T21:50:28.597 回答