重用已加载的JavaScript

时间:2013-08-29 19:04:41

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

目标

正确重用已加载的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个具有相同提案的脚本。

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

重复的问题?

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

1 个答案:

答案 0 :(得分: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;,这会导致上述代码再次请求新的脚本标记。只需删除/注释掉该行。