<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true">
</script>
<script type="text/javascript">
function importScript() {
var mapScript = document.createElement("Script");
mapScript.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true";
mapScript.id = "mapScript";
document.getElementsByTagName("head")[0].appendChild(mapScript);
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
}
</script>
</head>
<body onload="/*importScript();*/initialize();">
<div id="map" style="width:100%; height:100%"></div>
</body>
</html>如果采取importScript()方式则出错,而直接<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true">
</script>引用则可以,为什么??通过chrome跟踪发现在 new google.maps.LatLng(-34.397, 150.644),这里出错,google.maps为object,而google.maps.LatLng为null,Why?
也就是动态载入成功了,因为google.maps不为null,但是为什么google.maps.LatLng为null??
求大神赐教!!
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true">
</script>
<script type="text/javascript">
function importScript() {
var mapScript = document.createElement("Script");
mapScript.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true";
mapScript.id = "mapScript";
document.getElementsByTagName("head")[0].appendChild(mapScript);
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
}
</script>
</head>
<body onload="/*importScript();*/initialize();">
<div id="map" style="width:100%; height:100%"></div>
</body>
</html>如果采取importScript()方式则出错,而直接<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true">
</script>引用则可以,为什么??通过chrome跟踪发现在 new google.maps.LatLng(-34.397, 150.644),这里出错,google.maps为object,而google.maps.LatLng为null,Why?
也就是动态载入成功了,因为google.maps不为null,但是为什么google.maps.LatLng为null??
求大神赐教!!
已经被混淆过,请使用自己的google api id替换测试,谢谢。
1 创建了一个 script
2 并指定了 src。注意,在给 script 指定 src 到 src 中的内容加载完毕,是有一个时间间隔的所以,在 src 里的内容没加载完成前,你调用了 src 中的一个函数,就会发生一个函数未定义exception
太复杂了,不解释太深,等会发代码教你解决方案
<script>
//追加事件,当加载完成后,调用回调函数
function bindEventLoaded(mapScript, callback){
if(mapScript.addEventListener) //火狐 谷歌 Opera
{
mapScript.addEventListener("load",
function(){
callback();
},
false
);
}
else if(mapScript.attachEvent) //IE
{
mapScript.attachEvent("onreadystatechange",
function(Dom){
if(Dom.srcElement.readyState=="loaded" || Dom.srcElement.readyState=="complete"){
callback();
}
}
);
}
}
function createScript(){
var mapScript = document.createElement("Script");
bindEventLoaded(mapScript, function(){alert(google.maps);});//当 script 标签加载完 src 中的内容后,再调用里面存在的函数
mapScript.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true";
mapScript.id = "mapScript";
document.getElementsByTagName("head")[0].appendChild(mapScript);
alert(google.maps); //这里是不能调用的,这里调用时,可能 src 还没加载完
}
</script>
</head>
<body onload="createScript()">
</body>
if(google && google.maps && google.maps.LatLng){
initialize();
}else{
setTimeout(arguments.callee);
}
})();
if(window.navigator) {
if(google && google.maps && google.maps.LatLng){
navigator.geolocation.getCurrentPosition(displayLocation , displayError,options);
}else{
setTimeout(getMyLocation);
return;
}
}不论执行多少次,始终不能得到google.maps.LanLng的值,LanLng是一个构造函数,这个会因为构造函数有影响么?
然后直接调用 该js文件中的相关属性 这个时候js文件还没加载完毕(肯定的)所以 一般可以在js dom的加载回调事件中 执行你的代码 不过这个又牵涉到 浏览器的兼容性所以我现在一般 写的 反复循环的 代码
当有 某个对象
存在 则调用相关代码
不存在 则继续调用循环代码
这个为什么是肯定的???实验下来应该是这样子的,不过想从理论上讨论一下。
按照道理来说http同时有2个线程访问资源,而javascript是单线程执行,我通过动态script加载js时候,加载过程中使用的是http的线程还是javascript执行线程?一般来说加载js过程会锁住dom的加载及执行,那么也就是应该加载完成才能继续执行后面的方法了吧。
所以很多js引用必须强调顺序,后面的用到js库里面方法的函数,必须在的<script src=xx.js>标签后面,来保证xx.js加载完成,动态加载script不能保证这个顺序么?
比如
var mapScript = document.createElement("Script");
mapScript.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyD3dfd2O_9xqsqnfasdfKzJ3q2kdfggreQuVNM&sensor=true";
mapScript.id = "mapScript";
document.getElementsByTagName("head")[0].appendChild(mapScript);
alert(google.maps); //这里是不能调用的,这里调用时,可能 src 还没加载完??
//我的理解是这个肯定可以调用了但是javascript还有一点是根据<script>标签分段加载,难道是这个的影响??
我的理解与实际不符,但是我又不知道正确的理解方式,希望大家能够指正,非常感谢。
如果使用 document.createElement("Script"); 就是异步的,你的理解错了,所以总也想不通
function getMyLocation() {
if(window.navigator) {
if(google && google.maps && google.maps.LatLng){
navigator.geolocation.getCurrentPosition(displayLocation , displayError,options);
}else{
setTimeout(getMyLocation);
return;
}
}function initialize() {
var mapScript = document.createElement("Script");
bindEventLoaded(mapScript, getMyLocation);//当 script 标签加载完 src 中的内容后,再调用里面存在的函数
mapScript.src = "http://maps.google.com/maps/api/js?sensor=true";
mapScript.id = "mapScript";
document.getElementsByTagName("head")[0].appendChild(mapScript);
}
window.onload = initialize;结合使用了@clark_kidd 、@KK3K2005 两位的做法,但是仍然有问题,即
Google.maps是有值,但是google.map.LanLng为undefined。
chorme截图如下:估计这个已经不是加载顺序问题了,不论执行多少次,始终不能得到google.maps.LanLng的值,LanLng是一个构造函数,这个会因为构造函数有影响么?
google.map.LatLng
google.maps.LatLng
google.maps.LatLng
没有笔误,我重新看了一下,上面是我从代码复制回来的。
google.maps.LatLng,这里是复制的。
找到原因了http://maps.google.com/maps/api/js?sensor=true 这个js打开后,发现有这么一段代码function getScript(src) {
document.write('<' + 'script src="' + src + '"' +
' type="text/javascript"><' + '/script>');
}
//之后的调用
getScript("http://maps.gstatic.com/intl/zh_cn/mapfiles/api-3/12/8/main.js");
document.write,居然是 document.write!!document.write 有一个特性,那就是:
页面没有加载完时,会在当前代码位置 write
页面加载完后,再调用,会把 body 中的内容清空在 write所以,<script src="http://maps.google.com/maps/api/js?sensor=true"></script> 时,是正常的,而 window.onload 后发生的事,符合了页面加载完成这一条件,document中的东西都被清理了……其中包括 getScript("http://maps.gstatic.com/intl/zh_cn/mapfiles/api-3/12/8/main.js");输出的标签……,所以自然就没有 LatLng 了……
<script>
document.write("这里输出是正常的");
</script>
位置正常
</head>
<body>
<input type="button" value="document.write after loaded" onclick="document.write('清空了,居然清空了……')">
</body>
要不,google改api
要不,你只有写死 <script></script> 一条路……
总算找到原因了,我太过相信google的api了,所以压根没有从这方面想,太感谢你了,终于得出结论了。哈哈哈,大笑三声。
也感谢 @KK3K2005, 通过这个问题回顾了很多知识。