![](/img/trans.png)
[英]It's possible to remove controls from Google Maps with javascript without creating the function?
[英]Is it possible to initialize Google Maps asynchronously without creating a global callback function?
我正在嘗試編寫一個可重復使用的插件模塊,以異步方式加載Google Maps
並返回一個承諾。
但是,在“幕后”創建全局回調函數存在可重用性的缺點。 如果任何其他庫碰巧使用相同的命名空間,則可能導致錯誤的副作用。
我的問題 - 有沒有辦法在不創建全局變量的情況下實現這種效果。
下面是創建“邪惡”全局回調的代碼:
// Google async initializer needs global function, so we use $window
angular.module('GoogleMapsInitializer')
.factory('Initializer', function($window, $q){
// maps loader deferred object
var mapsDefer = $q.defer();
// Google's url for async maps initialization accepting callback function
var asyncUrl = 'https://maps.googleapis.com/maps/api/js?callback=';
// async loader
var asyncLoad = function(asyncUrl, callbackName) {
var script = document.createElement('script');
//script.type = 'text/javascript';
script.src = asyncUrl + callbackName;
document.body.appendChild(script);
};
// Here is the bad guy:
// callback function - resolving promise after maps successfully loaded
$window.googleMapsInitialized = function () {
mapsDefer.resolve();
};
// loading google maps
asyncLoad(asyncUrl, 'googleMapsInitialized');
return {
// usage: Initializer.mapsInitialized.then(callback)
mapsInitialized : mapsDefer.promise
};
})
用於從您引用的跨源域上的服務器獲取數據的腳本加載技術是JSONP。 你可以在這里閱讀更多相關信息。 根據定義,JSONP只能通過調用全局范圍的函數來工作。
所以,直接回答你的問題:沒有全局函數,你不能使用JSONP跨源技術 - 這就是機制的工作原理。 腳本在全局命名空間中執行,它必須調用它可以從全局命名空間訪問的函數。 甚至jQuery和YUI都是這樣做的,用於實現JSONP。
而且,由於您使用的是Angular,因此它已經內置了JSONP功能。 請參閱此處的doc,這樣您就不必創建自己的機制來執行此操作。
但是,這就是說,如果你自己制作,你可以通過采取一些預防措施使你創建的全局名稱更隨機,使你的全局函數與其他人的代碼或甚至與你的庫的另一個實例發生碰撞的可能性大大降低。
這是一個如何使任何類型的命名沖突的幾率非常小的例子。 這使用三種技術:
這是您實現這些方面的代碼。
// Google async initializer needs global function, so we use $window
angular.module('GoogleMapsInitializer')
.factory('Initializer', function($window, $q){
// maps loader deferred object
var mapsDefer = $q.defer();
// Google's url for async maps initialization accepting callback function
var asyncUrl = 'https://maps.googleapis.com/maps/api/js?callback=';
// async loader
var asyncLoad = function(asyncUrl, callbackName) {
var script = document.createElement('script');
//script.type = 'text/javascript';
script.src = asyncUrl + callbackName;
document.body.appendChild(script);
};
// generate a unique function name
// includes prefix, current time and random number
var fname = "__googleMapsInitialized_" +
(new Date().getTime()) + "_" +
(Math.random() + "").replace(".", "");
// callback function - resolving promise after maps successfully loaded
$window[fname] = function () {
mapsDefer.resolve();
// remove the global now that we're done with it
delete $window[fname];
};
// loading google maps
asyncLoad(asyncUrl, fname);
return {
// usage: Initializer.mapsInitialized.then(callback)
mapsInitialized : mapsDefer.promise
};
})
演示獨特的函數名稱生成器: http : //jsfiddle.net/jfriend00/oms7vc6o/
PS我自己並不認識Angular,但似乎Angular已經知道如何單獨進行JSONP調用,因此您不必在此處制作自己的解決方案。 有關詳細信息,請參閱此Angular文檔頁面以及此其他問題和本文 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.