0

目标

正确重用已加载的 JavaScript。

问题

我正在使用 Google Maps API V3 动态生成地图,我需要重用它。如何?

场景

Index.html上,有以下脚本:

var gMapsLoaded = false;

window.gMapsCallback = function () {
    gMapsLoaded = true;
    $(window).trigger('gMapsLoaded');
}

window.loadGoogleMaps = function () {
    if (gMapsLoaded) return window.gMapsCallback();
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type", "text/javascript");
    script_tag.setAttribute("src", 
        "http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
    (document.getElementsByTagName("head")[0]
     || document.documentElement).appendChild(script_tag);
}

当我单击某个按钮以显示地图时,我的应用程序会调用此脚本:

[...]

var geocoder;
var map;
var address = context.address();

function initialize() {
    var mapDiv = document.getElementById("map_canvas");
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
        zoom: 15,
        center: latlng,
        mapTypeControl: true,
        mapTypeControlOptions: 
           { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
        navigationControl: true,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(mapDiv, myOptions);

    if (geocoder) {
        geocoder.geocode({ 'address': address }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
                    map.setCenter(results[0].geometry.location);

                    var infowindow = new google.maps.InfoWindow(
                        {
                            content: '<b>' + address + '</b>',
                            size: new google.maps.Size(150, 50)
                        });

                    var marker = new google.maps.Marker({
                        position: results[0].geometry.location,
                        map: map,
                        title: address
                    });

                    google.maps.event.addListener(marker, 'click', function () {
                        infowindow.open(map, marker);
                    });

                } else {
                    alert("No results found");
                }
            } else {
                alert
                    ("Geocode was not successful 
                     for the following reason: " + status);
            }
        });
    }

    gMapsLoaded = false;
}

$(window).on('gMapsLoaded', initialize);
window.loadGoogleMaps();

如您所见,应用程序总是调用调用外部文件的loadGoogleMaps();函数。.js如果我单击 5 个不同的地图,我会得到 5 个具有相同提案的脚本。

有人有解决这个问题的想法吗?

重复的问题?

是的,我认为问题的本质是重复的,但核心不是。

4

1 回答 1

1

如您所见,应用程序始终调用 loadGoogleMaps(); 调用外部 .js 文件的函数。如果我单击 5 个不同的地图,我会得到 5 个具有相同提案的脚本。

这是不正确的。第一次完全加载后,第一行的 if 语句将提前返回,从而防止您多次包含它。

写的方式没有错。

jsFiddle

var gMapsLoaded = false;

window.gMapsCallback = function () {
    gMapsLoaded = true;
    $(window).trigger('gMapsLoaded');
}

window.loadGoogleMaps = function () {
    if (gMapsLoaded) return window.gMapsCallback();
    console.log('Generating new script tag');
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type", "text/javascript");
    script_tag.setAttribute("src", 
        "http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
    (document.getElementsByTagName("head")[0]
     || document.documentElement).appendChild(script_tag);
}

$(window).on("gMapsLoaded",function(){
    console.log("gMapsLoaded");
});
$(function(){
    $("button").on("click",window.loadGoogleMaps);
});

现在,如果您在它尚未加载的情况下非常快地单击它 5 次,它可能会加载多次。您应该在单击事件通常发生之前自行调用该函数以防止这种情况发生。


更新:

在您的initialize()方法结束时,您正在使用gMapsLoaded = false;它导致上述代码再次请求一个新的脚本标签。只需删除/注释掉该行。

于 2013-08-29T19:13:55.300 回答