如何从函数内部设置javascript变量?

时间:2009-06-03 11:29:41

标签: javascript variables

请看下面的代码。当i == 0的值时,警报1按逻辑打印变量值。但是,如果我尝试打印值(警报2),它只是说“未定义,未定义”。我的问题是,为了使第二次警报(警报2)中打印的值与警报1相同,我必须做出哪些更改?

var testPoint = [];

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map_canvas"));
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(52.5271463402545, -1.50573921491311), 8, G_HYBRID_MAP);

    GDownloadUrl("controllers/gmap_genxml2.php", function(data) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        if(i == 0) {
            testPoint["lat"] = parseFloat(markers[i].getAttribute("lat"));
            testPoint["lng"] = parseFloat(markers[i].getAttribute("lng"));

            /********* ALERT 1 ***********/
            alert(testPoint["lat"]+" "+testPoint["lng"]);
            /********* ALERT 1 End ***********/
        }
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");
        var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, address, type);
        map.addOverlay(marker);
      }
    });

    /********* ALERT 2 ******************/
    alert(testPoint["lat"]+" "+testPoint["lng"]);
    /********* ALERT 2 Start ***********/
  }
}

感谢您的帮助。 节目播音员

4 个答案:

答案 0 :(得分:4)

你必须意识到很多JavaScript都是基于事件的。以下是发生的事情:

GDownloadUrl接受回调。第二个参数是一个在请求完成时将被称为的函数不会立即被召唤。这个很重要。关闭对GDownloadUrl的调用后,Javascript继续运行。它不等待请求完成。事实上,如果您同时保留两个警报,您将看到警报2将在警报1之前触发。因此,如果您想在获取这些变量时对这些变量执行特定操作,则应将该代码移至一个函数,并在GDownloadUrl回调中调用它。这就是JavaScript的工作方式,你会习惯它。

答案 1 :(得分:1)

两个对象键lat和lng仅在GDownloadUrl调用的回调函数中有效。

你必须等待它执行一次,然后才能拥有正确的值。

我建议您在此回调函数结束时移动警报2。

答案 2 :(得分:1)

您正在将函数指针传递给另一个函数调用。这并不一定会使代码执行。时机可能已关闭。调用该函数时,ALERT 1正在发生(很棒),但是在调用该函数之前实际上正在执行ALERT 2!

在打印testPoint的内容之前,请尝试延迟1秒。

答案 3 :(得分:0)

    testPoint = [];

    // This global var is introduced to mark that testPoint values are not yet loaded.
    var isLoaded = false;

    function load() {

    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        map.setCenter(new GLatLng(52.5271463402545, -1.50573921491311), 8, G_HYBRID_MAP);

    GDownloadUrl("controllers/gmap_genxml2.php", function(data) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        if(i == 0) {
                testPoint["lat"] = parseFloat(markers[i].getAttribute("lat"));
                testPoint["lng"] = parseFloat(markers[i].getAttribute("lng"));

                /********* ALERT 1 ***********/
                alert(testPoint["lat"]+" "+testPoint["lng"]);
                /********* ALERT 1 End ***********/

                // Set it to true to indicate that testPoint array is already loaded.
                isLoaded = true;
        }
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");
        var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, address, type);
        map.addOverlay(marker);
      }
    });

    /********* ALERT 2 ******************/
     // Try to alert testPoint each 0.5 sec until we can successfully do it.
     function alert2() {
         // if testPoint is loaded - then alert it, if not then try in 0.5 sec.
         if (isLoaded) {
              alert(testPoint["lat"]+" "+testPoint["lng"])
         } else {
              setTimeout(alert2, 500);
         }
     };

     alert2();
    /********* ALERT 2 Start ***********/
  }
}