Ответ 1
оказывается, что он имеет отношение к ng-Route
и порядок загрузки script
написал директиву и поместил API script поверх всего.
Я следую этому руководству, в основном копирую весь код
https://developers.google.com/maps/documentation/javascript/tutorial
но получил сообщение о том, что функция initMap не является функцией. Я использую angularjs в моем проекте, может ли это быть проблемой?
Я скопировал один и тот же код в плункер, и он отлично работает... Каковы возможные проблемы?
оказывается, что он имеет отношение к ng-Route
и порядок загрузки script
написал директиву и поместил API script поверх всего.
Фактически ошибка генерируется initMap в Google api script
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
поэтому, когда загружается API Google Map, выполняется функция initMap. Если у вас нет функции initMap, генерируется initMap, а не функция.
Итак, в основном вам нужно сделать один из следующих вариантов:
&callback=angular.noop
, если вы просто хотите пустую функцию() (только если вы используете angular)Мое объяснение этой проблемы:
.....&callback=initMap" async defer></script>
заставляет этот скрипт загружать асинхронно (параллельно с DOM), а после загрузки - выполнять функцию initMap. ОБРАТИТЕ ВНИМАНИЕ, что initMap() в глобальной области! Мы не можем объявить наш initMap() после google-скрипта, потому что он должен быть уже в момент завершения асинхронной загрузки. Хотя мы не можем загрузить наш скрипт до этого, потому что нам нужна функция google для выполнения нашего. Это похоже на замкнутый круг.
async defer
&callback=initMap
в атрибуте src
<script
с вашим кодом после google script.....&callback=initMap" async defer></script>
как есть<script
tag после вашего скриптанапиши в свой сценарий
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
}
и если вы напишите его в глобальном масштабе, это будет работать независимо от того, какой код загружается быстрее: ваш (синхронизация) или Google (асинхронный). Чаще ваши победы
В течение нескольких дней я боролся с этой очень популярной в последние несколько месяцев проблемой - "initMap - это не функция".
Эти две темы помогли мне:
Почему карта открывается иногда, а иногда нет. Это зависит от нескольких факторов, таких как скорость соединения, среда и т.д. Поскольку функция инициализации иногда запускается после запуска API карт Google, поэтому карта не отображается, и консоль браузера выдает ошибку. Для меня удаление только атрибута async устранило проблему. Атрибут defer остается.
Если присутствует асинхронность: сценарий выполняется асинхронно с остальной частью страницы (сценарий будет выполняться, пока страница продолжит синтаксический анализ) Если асинхронность отсутствует и присутствует отсрочка: сценарий выполняется после завершения анализа страницы. нет ни асинхронного, ни отложенного: скрипт извлекается и выполняется немедленно, прежде чем браузер продолжит синтаксический анализ страницы. Источник - http://www.w3schools.com/tags/att_script_defer.asp
Надеюсь, это поможет. Приветствия.
Проблема связана с атрибутом async в теге script. Функция обратного вызова пытается вызвать "initMap()", если она не существует на момент завершения запроса.
Чтобы решить эту проблему, я разместил карты Goole Api script ниже script, где была объявлена моя функция initMap.
Надеюсь, что это поможет
Удаление =initMap
работало для меня:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback"></script>
Это может показаться очевидным, но на всякий случай: если кто-то разместил JS-код внутри $(document). уже вот так:
$(document).ready(function() {
... Google Maps JS code ...
}
Тогда проблема связана с использованием async
defer
при загрузке библиотеки API Карт Google, она будет загружаться асинхронно, а когда она закончит загрузку, будет искать функцию обратного вызова, которая должна быть доступна к ней.
Итак, вам просто нужно поместить код вне $(document).ready и:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
async defer></script>
в самом низу, поэтому ваша страница загружает FAST: -)
Решено путем добавления
<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 () ...
, это тоже сработало бы.
Я использую React, и я упомянул & callback = initMap в скрипте, как показано ниже
<script
src="https://maps.googleapis.com/maps/api/js?
key=YOUR_API_KEY&callback=initMap">
</script>
затем просто удаляется часть &callback=initMap
теперь такой ошибки нет, так как window.initMap не является функцией консоли.
Создайте метод initMap между тегом "" или загрузите файл javascript перед вызовом google api.
<script src="Scripts/main.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=abcde&libraries=places&callback=initMap" async defer></script>
Поместите это в свой html-элемент (взятый с официального веб-сайта angular.js):
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
Я считаю, что вы использовали более старые файлы angular.js, так как у вас нет проблем в plunker, и поэтому вы получили указанную ошибку.
Может быть, ваша функция initMap находится в функции $(document).ready. Если это так, то это не сработает, оно должно быть вне любых других функций.
В дополнение к @DB.Null ответ, я использовал Function.prototype
как функцию no-op (no-operation) на # 3 вместо angular.noop
(у меня нет angular в моем проекте).
Итак, это...
<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&callback=Function.prototype" type="text/javascript"></script>
В моем случае ранее была проблема с форматированием, поэтому ошибка была следствием чего-то другого. Мой сервер рендерил значения широты/долготы запятыми, а не точками, из-за разных региональных настроек.
Ваш метод обратного вызова, вероятно, не доступен во всем мире. в моем случае я использовал транспонированные коды ES6 через веб-пакет, что сделало мой метод обратного вызова более не глобальным.
Попытайтесь явно прикрепить ваш метод обратного вызова к window
как это делается сразу после объявления метода обратного вызова, и посмотрите результат
window.initMap = initMap;
это сработало для меня.
У меня была похожая ошибка. Ответы здесь помогли мне понять, что делать.
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-->
<!-- not asyn defer keyword-->
<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 called yet
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), чтобы обойти это.
Ошибка заключается в том, что во время вызова API-интерфейса Google Maps функция initMap() не была выполнена.
main.js//Это работает
const mapDisplayElement = document.getElementById('map');
// The address is Uluru
const address = {lat: -25.344, lng: 131.036};
// Run the initMap() function imidiately,
(initMap = () => {
// 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 });
})();
В моем случае я решил это так:
function initMap() {
if($('#map').length > 0) {
// your code
}
}