【问题标题】:AJAX call in an Infowindow: Scope Issue信息窗口中的 AJAX 调用:范围问题
【发布时间】:2014-01-15 01:40:38
【问题描述】:

或者至少我认为这是一个范围问题,如果我错了,请纠正我。

我有一个在我的地图上生成标记的 for 循环。每个信息窗口使用对 ajax 函数的回调来加载不同的内容。

我已简化此示例以概述问题。

var xhr = "";
var infowindow = new google.maps.InfoWindow();
var marker, i;
var polylineCoordinates = [new google.maps.LatLng(78.782762, 17.917843),
                           new google.maps.LatLng(-0.829439, -91.112473),
                           new google.maps.LatLng(15.066156, -23.621399),
                          ]


function createHttpRequest() {
    try {   
        xhr = new XMLHttpRequest();
        return xhr;
        }
        catch (e)
        {
            //assume IE6
            try {
            xhr = new activeXBbject("microsoft.XMLHTTP");
            return xhr;
            }
            catch (e)   {
                return alert("Unable to create an XMLHttpRequest object");
            }
        }
}



  function initialize() {

    var mapOptions = {
      center: new google.maps.LatLng(78.782762,17.917843),
      zoom: 10,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
        map = new google.maps.Map(document.getElementById("map_canvas"),
        mapOptions);
  }



//I recreated the polylineCoordinates array (see above)
//to try and replicate and real array in the script

for (i = 0; i < polylineCoordinates.length; i++) {
    marker = new google.maps.Marker({
        position: polylineCoordinates[i],
        map: map
    });

    google.maps.event.addListener(marker, 'click', (function (marker, i) {
        return function () {
            infowindow.setContent("<div id=\"infowindow\">" + getStationInfo(infoWindowDiv) + "</div>");
            infowindow.open(map, marker);

        }
    })(marker, i));

} //End adding markers loop


            function infoWindowDiv(stationInfo) {
                var add = document.createTextNode(stationInfo);
                document.getElementById("infowindow").appendChild(add);
            }


            function getStationInfo(callback) {
                //createHttpRequest() exists globally
                var xhr = createHttpRequest();
                var url = "stations.php" //edited out the original URL
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var stationInfo = "This is a Test";
                        return callback(stationInfo)
                    } //end readyState

                } //end readystatechange
                xhr.open("GET", url, true);
                xhr.send(null);
            } //end getStationInfo

小编辑:将函数移出循环

编辑 2: ajax 调用没有任何问题,为了示例代码而编辑了 url。请注意,最终输出在信息窗口中显示“这是一个测试”,清楚地表明执行了成功的回调。此外,请注意没有 responseText 或 responseXml。被发回的变量与url无关

回调工作正常,但由于某种原因,它顶部带有可怕的“未定义”。
控制台什么也没显示。
输出:

undefined
This is a test

我做错了什么?如果有效,怎么可能是未定义的?

【问题讨论】:

  • 您正在循环内定义函数 infoWindowDiv 和 getStationInfo,即您正在重新创建它们 polylineCoordinates.length 次数。将它们移出该循环。这不应该导致您的问题,这只是不好的做法
  • @duncan,感谢您的意见。函数现在在循环之外,但功能保持不变......
  • 你的createHttpRequest函数在做什么?
  • 请提供足够的代码来复制问题(或小提琴或指向存在问题的页面的链接)。您不能在 getStationInfo 的 onreadystatchange 函数中返回任何内容。
  • 它创建了一个 XMLHttpRequest()。我非常有信心这不是问题,因为它在脚本的不同部分都可以正常工作。我没有添加它,因此我可以将示例代码保持在主题上。我现在再补充一些。

标签: javascript ajax google-maps google-maps-api-3


【解决方案1】:

发生了什么:

  1. 您点击信息窗口
  2. getStationInfo(infoWindowDiv) 被调用,触发 AJAX 请求,但没有返回任何有用的信息(“未定义”,没有返回语句)
  3. AJAX 函数将遇到错误(url“此时不需要”不会导致 onreadystatechange 函数触发)。但你告诉我们这不是问题。
  4. 脚本遇到 javascript 错误 Uncaught TypeError: Cannot call method 'appendChild' of null,因为 id 为 infowindow 的 div 尚未附加到 DOM。

建议在 infowindow 上添加一个事件侦听器,以便在呈现 (domready) 之前不要尝试访问 id="infowindow" 的 div。

工作代码:

    var xhr = "";
    var infowindow = new google.maps.InfoWindow();
    var map = null;
    var marker, i;
    var polylineCoordinates = [new google.maps.LatLng(78.782762, 17.917843),
                               new google.maps.LatLng(-0.829439, -91.112473),
                               new google.maps.LatLng(15.066156, -23.621399)
                              ]


      function initialize() {
        var mapOptions = {
          center: new google.maps.LatLng(78.782762,17.917843),
          zoom: 10,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
            map = new google.maps.Map(document.getElementById("map_canvas"),
            mapOptions);

    for (i = 0; i < polylineCoordinates.length; i++) {
        marker = new google.maps.Marker({
            position: polylineCoordinates[i],
            map: map
        });

        google.maps.event.addListener(marker, 'click', (function (marker, i) {
            return function () {
                infowindow.setContent("<div id=\"infowindow\" style=\"height:50px;width:200px;\"></div>");
                infowindow.open(map, marker);
            google.maps.event.addListenerOnce(infowindow,"domready", function(){
                  getStationInfo(infoWindowDiv);
                });
        })(marker, i));

    } //End adding markers loop

    }
            function infoWindowDiv(stationInfo) {
                var add = document.createTextNode(stationInfo);
                document.getElementById("infowindow").appendChild(add);
            }


            function getStationInfo(callback) {
                var stationInfo = "This is a Test";
                callback(stationInfo)
            } //end getStationInfo

    google.maps.event.addDomListener(window, 'load', initialize);

【讨论】:

  • Ajax 函数工作得很好,为了示例,我只是编辑了原始 url。请注意,最终输出在信息窗口中显示“这是一个测试”,它清楚地表明执行了成功的回调。此外,请注意没有 responseText 或 responseXml。被发回的变量与 url 无关。这绝对不是脚本的问题......
  • 很好。如果您希望我们做的不仅仅是猜测,我们要么必须制作一个有效的 URL,要么您需要提供一个。当我尝试运行您的代码时,我得到了相当明显的 javascript 错误 (Uncaught TypeError: Cannot call method 'appendChild' of null &lt;page name&gt;:80)
  • 您不妨将 google.com 设置为 url!在 xhr.readyState == 4 && xhr.status == 200 的范围内没有定义 responseText! url 不是问题的根源。
  • 如果您尝试运行脚本,只需将 url 变量设置为任何有效的值,它就会通过。请注意,我们不会从中提取任何信息。
  • 附加问题:第二个事件侦听器有效,但作为回报,我遇到了一个附加问题:第一次单击标记时一切正常,第二次单击它会得到相同的输出两次,它就是这样建立起来的。例如,如果我们使用alert() 进行测试,第一次单击信息窗口时,您将获得一个警报,第二次,两个警报,第三次单击,三个警报......等等。我很难理解这种行为,有什么想法吗?希望我把问题说得够清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
相关资源
最近更新 更多