求教:google map api通过动态

UEAnswer 2013-04-12 04:19:21
<!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??
求大神赐教!!
...全文
304 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
UEAnswer 2013-04-16
  • 打赏
  • 举报
回复
day day up
UEAnswer 2013-04-16
  • 打赏
  • 举报
回复
@clark_kidd 总算找到原因了,我太过相信google的api了,所以压根没有从这方面想,太感谢你了,终于得出结论了。哈哈哈,大笑三声。 也感谢 @KK3K2005, 通过这个问题回顾了很多知识。
clark_kidd 2013-04-16
  • 打赏
  • 举报
回复
给你一个令人郁闷的结论 要不,google改api 要不,你只有写死 <script></script> 一条路……
clark_kidd 2013-04-16
  • 打赏
  • 举报
回复
我们来做个实验
<script>
	document.write("这里输出是正常的");
</script>
位置正常
</head>
<body>
<input type="button" value="document.write after loaded" onclick="document.write('清空了,居然清空了……')">
</body>
clark_kidd 2013-04-16
  • 打赏
  • 举报
回复
找到原因了 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 了……
UEAnswer 2013-04-16
  • 打赏
  • 举报
回复
@clark_kidd 谢谢, google.maps.LatLng 没有笔误,我重新看了一下,上面是我从代码复制回来的。 google.maps.LatLng,这里是复制的。
clark_kidd 2013-04-16
  • 打赏
  • 举报
回复
你是不是笔误了?我也笔误了…… google.maps.LatLng
clark_kidd 2013-04-16
  • 打赏
  • 举报
回复
你是不是笔误了? google.map.LatLng
clark_kidd 2013-04-15
  • 打赏
  • 举报
回复
在 DOM对象 script 上追加 load 事件的监听是最正统的解决方案,这个已经经过项目的验证证实了的
clark_kidd 2013-04-15
  • 打赏
  • 举报
回复
关于这个异步问题,你自己最好写个例子测试一下,以前我遇到这个问题的时候也很费解,不要用 setTimeout,因为你永远不知道对方的服务器网络质量有多好(差)
clark_kidd 2013-04-15
  • 打赏
  • 举报
回复
<script src="xxx"></script> 如果是写在页面中的,那么就是非异步 如果使用 document.createElement("Script"); 就是异步的,你的理解错了,所以总也想不通
UEAnswer 2013-04-15
  • 打赏
  • 举报
回复
@KK3K2005 :直接调用 该js文件中的相关属性 这个时候js文件还没加载完毕(肯定的) 这个为什么是肯定的???实验下来应该是这样子的,不过想从理论上讨论一下。 按照道理来说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>标签分段加载,难道是这个的影响?? 我的理解与实际不符,但是我又不知道正确的理解方式,希望大家能够指正,非常感谢。
KK3K2005 2013-04-15
  • 打赏
  • 举报
回复
因为我看你代码 是异步加载了一个 js文件 然后直接调用 该js文件中的相关属性 这个时候js文件还没加载完毕(肯定的) 所以 一般可以在js dom的加载回调事件中 执行你的代码 不过这个又牵涉到 浏览器的兼容性 所以我现在一般 写的 反复循环的 代码 当有 某个对象 存在 则调用相关代码 不存在 则继续调用循环代码
UEAnswer 2013-04-15
  • 打赏
  • 举报
回复
function getMyLocation() {    
if(window.navigator) {
if(google && google.maps && google.maps.LatLng){
navigator.geolocation.getCurrentPosition(displayLocation , displayError,options);

}else{
setTimeout(getMyLocation);
return;
}
}


不论执行多少次,始终不能得到google.maps.LanLng的值,LanLng是一个构造函数,这个会因为构造函数有影响么?
UEAnswer 2013-04-15
  • 打赏
  • 举报
回复
引用 7 楼 KK3K2005 的回复:
(function(){ if(google && google.maps && google.maps.LatLng){ initialize(); }else{ setTimeout(arguments.callee); } })();
感谢你,请问这段代码是否实现的是循环调用当前匿名方法,直到initialize();成功?
UEAnswer 2013-04-15
  • 打赏
  • 举报
回复
首先感谢 @clark_kidd 、@KK3K2005 两位的帮助。


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是一个构造函数,这个会因为构造函数有影响么?
KK3K2005 2013-04-13
  • 打赏
  • 举报
回复
(function(){ if(google && google.maps && google.maps.LatLng){ initialize(); }else{ setTimeout(arguments.callee); } })();
UEAnswer 2013-04-13
  • 打赏
  • 举报
回复
等到周一有台式机再好好请教您,再次感谢。据我理解,通过插入script元素方式虽然是动态,但是并非异步,应该src文件加载完成之后才继续执行init的方法。
UEAnswer 2013-04-13
  • 打赏
  • 举报
回复
你好,首先感谢你的帮助,我也考虑是没有加载完的原因,但是Google.maps是有值,可以通过chrome查看,但是google.map.lanlng为null,这个是我想不通的地方,周末在家使用ipad回复十分不便,描述可能不是很清楚,敬请谅解。
clark_kidd 2013-04-12
  • 打赏
  • 举报
回复
<head>
<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>
加载更多回复(3)

87,991

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧