类型错误:window.initMap 不是函数
Posted
技术标签:
【中文标题】类型错误:window.initMap 不是函数【英文标题】:TypeError: window.initMap is not a function 【发布时间】:2015-12-06 09:59:16 【问题描述】:我在跟着这个教程,基本上把代码全部复制过来
https://developers.google.com/maps/documentation/javascript/tutorial
但收到一个错误,提示 initMap 函数不是函数。 我在我的项目中使用了 angularjs,这会导致问题吗?
我将相同的代码复制到 plunker 中,它工作得很好...... 有哪些可能的问题?
【问题讨论】:
使用最新版本的angular.js,你的问题应该解决了 如果您删除任何包含函数(例如 JQuery 的 document.ready),您的错误会消失吗? 【参考方案1】:其实这个错误是由 Google 的 api 脚本中的 initMap 产生的
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
所以基本上在加载 Google Map API 时会执行 initMap 函数。 如果没有initMap函数,则生成initMap is not a function错误。
所以基本上你要做的是以下选项之一:
-
创建 initMap 函数
将回调函数替换为您自己的一个为相同目的创建但将其命名为其他名称的回调函数
如果您只想要一个空函数(),请替换
&callback=angular.noop
(仅当您使用 angular 时)
【讨论】:
即使函数 initMap 存在,它一直在说同样的事情 您的 initMap 函数是否在回调事件之前加载?您能否提供错误或如何定义功能?提示:这个函数必须是全局的,或者如果它是一个对象的属性,你必须更新gmap链接中的回调函数指向这个特定的属性,并确保对象在回调事件之前被实例化。跨度> 为什么我会因为这条评论而得到负分?问题是因为 wordpress 的所见即所得 html 编辑器。它为插入的 js 代码中的空行插入随机标记。我把js代码写了一行,问题消失了。
(第一个解决。谢谢)--> window.initMap = function() ; 我遇到了与 OP 相同的问题,并且我遵循相同的教程以及其他一些教程。我的问题是它是随机发生的,每 10 次加载一次,InitMap 就不是一个函数。您的评论实际上让我注意到 JS 是在 Map API 之后调用的,所以偶尔 API 会在 JS 之前完成然后调用尚未加载的 JS 中的函数,因此不存在(不一个函数)。将 JS 移到 API 调用上方,稍后重新加载 50 次,仍然没有错误。【参考方案2】:我对这个问题的解释:
.....&callback=initMap" async defer></script>
使脚本加载异步(与 DOM 并行)并在加载后执行 initMap 函数。 注意 initMap() 在全局范围内!我们不能在 google 的脚本之后声明我们的 initMap(),因为它现在应该已经存在完成异步加载。虽然我们不能在 before 之前加载我们的脚本,因为我们需要 google 的函数来执行我们的。这就像恶性循环。
三种解决方案:
第一个也是最差的:让 google 的脚本同步加载
-
删除
async defer
删除src
属性中的&callback=initMap
在你的代码后面加上<script
标签
第二和最好的:这样做 =)
-
保持
.....&callback=initMap" async defer></script>
原样
在你的脚本后面加上google的<script
标签
写在你的脚本中
function initMap() // now it IS a function and it is in global
$(() =>
initMap = function()
// your code like...
var map = new google.maps.Map(document.getElementById('map'), /*your code*/);
// and other stuff...
)
这允许您加载 google 的脚本异步并在此之后运行您的
第三个和奇怪的:它会工作......有时=)
做同样的事情,但只是写在全局范围内
function initMap()
// your code
如果你在全局范围内编写它,无论什么都可以 哪个代码加载更快,您的(同步)或谷歌的(异步)。更多时候你的胜利
【讨论】:
感谢您的回答。有效!你能详细说明你的第二个选择吗?我是 JQuery 的新手。 $(() => ),如何确保该方法在地图加载后运行?它像 document.ready 的简写吗? 我已经逐字添加了#2,我收到了这个错误:Uncaught SyntaxError: Unexpected token
。从这一行开始:var map = new google.maps.Map(document.getElementById('map'), ...);
导致该错误的原因是什么?
在 ... 中,您应该放置您的代码,而不是“...”。抱歉,我将其更改为评论。
为什么第一个解决方案更糟?就我而言,我不想在页面加载时调用地图。我想在单击特定元素时显示它。而且这个元素是从 WebSQL 动态加载的,因此,我什至不知道何时加载该元素,而且我很确定 google 脚本会加载得更快。在这种情况下,最好的解决方案应该是删除回调,并在我的元素被点击时调用地图,对吧?
@IsraelObanijesu,我会做类似的事情 -> 用户点击元素 -> 显示加载器 -> 加载谷歌地图 -> 初始化谷歌地图 -> 隐藏加载器。所以我什至不会在页面加载时加载谷歌地图,无论是同步还是异步。【参考方案3】:
过去几个月来,我一直在努力解决这个非常流行的问题——“initMap 不是一个函数”。
这两个线程帮助了我:
How to make a callback to Google Maps init in separate files of a web app
Defer attribute doesn't work with Google Maps API?
为什么地图有时打开有时不打开。这取决于连接速度、环境等几个因素。因为初始化函数有时会在 google maps API 启动后运行,这就是地图不显示并且浏览器控制台抛出错误的原因。对我来说,只删除 async 属性解决了这个问题。 defer 属性保持不变。
如果存在异步:脚本与页面的其余部分异步执行(脚本将在页面继续解析时执行) 如果 async 不存在且 defer 存在:当页面完成解析时执行脚本 如果 async 或 defer 都不存在:在浏览器继续解析页面之前立即获取并执行脚本 来源-http://www.w3schools.com/tags/att_script_defer.asp
希望对您有所帮助。干杯。
【讨论】:
太棒了!谢谢维克多! 只使用 defer(删除“async”后),它可以工作。谢谢。 删除“异步”后工作【参考方案4】:删除 =initMap
对我有用:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback"></script>
【讨论】:
我认为如果省略initMap,第一次加载时地图不会加载? 你是如何分别创建地图或调用你的回调的? 这与 Angular 完美配合,因为问题只是错误,其他一切都可以在没有任何 initMap 函数的情况下工作【参考方案5】:问题与脚本标签中的 async 属性有关。回调函数试图在请求完成时调用“initMap()”。
为了解决这个问题,我将 Goole Maps Api 脚本放在声明我的 initMap 函数的脚本下方。
希望对你有帮助
【讨论】:
【参考方案6】:这似乎很明显,但以防万一:如果有人将 JS 代码放在 $(document).ready 中,如下所示:
$(document).ready(function()
... Google Maps JS code ...
那就是问题所在,因为使用async
defer
在加载谷歌地图API库时,会异步加载,加载完成后会寻找回调函数,此时需要可用。
所以,你只需要将代码放在 $(document).ready,然后:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
async defer></script>
在最底部,因此您的页面加载速度很快 :-)
【讨论】:
您的答案就是有意义的答案。谢谢。如果你能解释 defer 的作用,那就太棒了。 :)【参考方案7】:添加解决
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&callback=initMap">
<!--
https://developers.google.com/maps/documentation/javascript/examples/map-geolocation
-->
</script>
在同一文件的开头,其中包含带有function initMap()
的其余代码。这绝对不是最好的解决方案,但它确实有效..
但我认为,如果您将function initMap()
转换为var=initMap()
,然后再转换为$(function () ...
,它也会起作用。
【讨论】:
真正的意义是什么?在脚本元素中有 HTML 注释?把 selfsame 放在开头?【参考方案8】:我正在使用 React,我在下面的脚本中提到了 &callback=initMap
<script
src="https://maps.googleapis.com/maps/api/js?
key=YOUR_API_KEY&callback=initMap">
</script>
然后刚刚删除了&callback=initMap
部分,现在没有window.initMap不是控制台中的函数这样的错误。
【讨论】:
但是如果该函数永远不会执行,你是如何加载地图的?【参考方案9】:您的回调方法可能无法全局访问。在我的例子中,我通过 webpack 使用了转译的 ES6 代码,这导致我的回调方法不再是全局的。
尝试在您的回调方法声明之后立即将您的回调方法显式附加到window
并查看结果
window.initMap = initMap;
它对我有用。
【讨论】:
【参考方案10】:在“”标签之间创建initMap方法或在调用google api之前加载javascript文件。
<script src="Scripts/main.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=abcde&libraries=places&callback=initMap" async defer></script>
【讨论】:
【参考方案11】:把它放在你的 html 正文中(取自 angular.js 官方网站):
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
我相信您使用的是一些较旧的 angular.js 文件,因为您在 plunker 中没有任何问题,因此您收到了指定的错误。
【讨论】:
【参考方案12】:原来它与ng-Route
和加载脚本的顺序有关
编写了一个指令,并将 API 脚本放在一切正常工作之上。
【讨论】:
我自己试过了,这并不能修复错误,只是将错误带到控制台窗口的顶部。【参考方案13】:我遇到了类似的错误。这里的答案帮助我弄清楚该怎么做。
index.html
<!--The div element for the map -->
<div id="map"></div>
<!--The link to external javascript file that has initMap() function-->
<script src="main.js">
<!--Google api, this calls initMap() function-->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY&callback=initMap">
</script>
main.js // 这会报错
// The initMap function has not been executed
const initMap = () =>
const mapDisplayElement = document.getElementById('map');
// The address is Uluru
const address = lat: -25.344, lng: 131.036;
// The zoom property specifies the zoom level for the map. Zoom: 0 is the lowest zoom,and displays the entire earth.
const map = new google.maps.Map(mapDisplayElement, zoom: 4, center: address );
const marker = new google.maps.Marker( position: address, map );
;
这里的答案帮助我找到了解决方案。 我使用了一个立即调用的函数 (IIFE) 来解决它。
错误是在调用google maps api时initMap()函数没有执行。
main.js // 这行得通
const mapDisplayElement = document.getElementById('map');
// The address is Uluru
// Run the initMap() function imidiately,
(initMap = () =>
const address = lat: -25.344, lng: 131.036;
// The zoom property specifies the zoom level for the map. Zoom: 0 is the lowest zoom,and displays the entire earth.
const map = new google.maps.Map(mapDisplayElement, zoom: 4, center: address );
const marker = new google.maps.Marker( position: address, map );
)();
【讨论】:
【参考方案14】:对我来说,主要区别在于函数的声明......
代替
function initMap()
...
成功了
window.initMap = function ()
...
【讨论】:
【参考方案15】:可能是您的 initMap 函数位于 $(document).ready 函数中。如果是,那么它将不起作用,它必须在任何其他功能之外。
【讨论】:
【参考方案16】:除了@DB.Null 的回答,我在#3 上使用Function.prototype
作为无操作(无操作)功能,而不是angular.noop
(我的项目中没有角度)。
所以这个...
<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&callback=Function.prototype" type="text/javascript"></script>
【讨论】:
【参考方案17】:在我的情况下,之前存在格式问题,因此该错误是由其他原因引起的。由于不同的区域设置,我的服务器使用逗号而不是句点呈现纬度/经度值。
【讨论】:
有趣。你是怎么知道的?【参考方案18】:我从脚本标签中删除了“initMap”的回调,并将回调放在我的 JavaScript 文件中。
<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY&callback=initMap"></script>
改为
<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY"></script>
所以第一个JS标签是我的。
<script async type=module src="js/app.js"></script>
<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY"></script>
我通过将以下内容添加到我的 app.js 文件中,从我的 JS 文件中调用了 initMap 函数。
initMap();
【讨论】:
【参考方案19】:就我而言,我必须在我的 Wordpress 网站上加载地图,问题是 Google 的 api 脚本在 initMap() 之前加载。因此,我延迟解决了这个问题:
<script>
function initMap()
// Your Javascript Codes for the map
...
<?php
// Delay for 5 seconds
sleep(5);
?>
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEYWY&callback=initMap"></script>
【讨论】:
以上是关于类型错误:window.initMap 不是函数的主要内容,如果未能解决你的问题,请参考以下文章