2015-05-27 2 views
1

Я пытаюсь динамически генерировать карту Google, когда пользователь отправляет форму, но карта не появляется в своем div при отправке формы.Вставить карту Google в динамически созданный div

Я тестировал, будет ли карта заполняться только на pageload, и это происходит, но при попытке использовать div, отображающий onclick, карта не отображается.

<form onsubmit="return false" action=""> 
    <input type="text" id="addLocation"/> 
    <button onclick="findLocation()" id="btnLocation">Find Location</button> 
</form> 

<div id="mapContainer"></div> 

Это JavaScript:

function findLocation(){ 
    var inputString = $('#addLocation').val(); 
    $('#mapContainer').html('<div id="mapCanvas"></div>'); 

    var apiRequest = $.ajax({ 
    url: 'http://xxxxx.net/json/'+ inputString, 
    dataType: 'json', 
    type: 'get', 
    }); 

    apiRequest.done(function(data){ 
    var lat = data['latitude']; 
    var lng = data['longitude']; 

    function initialize() { 
     var mapOptions = { 
     center: new google.maps.LatLng(lat, lng), 
     zoom: 8 
     }; 
     map = new google.maps.Map(document.getElementById('mapCanvas'), mapOptions); 
    } 

    // from GMaps API docs 
    function loadScript() { 
     var script = document.createElement('script'); 
     script.type = 'text/javascript'; 
     script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' + '&callback=initialize'; 
     document.body.appendChild(script); 
    } 
    window.onload = loadScript; 

    }); // ends .done statement 
} // ends findLocation 

Это должно быть то, что при нажатии на кнопку Find Расположение будет генерировать карту в mapCanvas DIV, но это не так.

Я узнал from the Google Maps API documentation, что если вы хотите асинхронно загружать карту, вы должны использовать эту функцию loadScript.

И да, карты divs имеют ширины и высоты в CSS, так что это не проблема. Я думаю, проблема связана с областями Javascript. Я делаю что-то неправильно с порядком или размещением звонков, просто не знаю, что.

+1

Возможно, вы имеете право на область видимости. Обратный вызов будет проходить в области окна, и он не сможет найти вашу функцию. Попробуйте установить 'window.initialize = initialize' и посмотреть, вызывает ли это карту OK. – sifriday

+0

Была хорошая идея, но я боюсь, что вызывать инициализацию не сделали. – PanicBus

+1

Также вам не хватает 'center:' в вашем mapOptions ... – sifriday

ответ

4

Во-первых, это неправда, что вы должны загружать API карт асинхронно, если хотите динамически создавать карту. Вы можете загрузить API либо с помощью асинхронного метода, либо с помощью обычного тега <script>. Загрузка API не создает карту; он просто загружает код. Карта не создается, пока вы не вызовете new google.maps.Map().

Таким образом, одним из простых решений было бы вернуться к тегу <script>, чтобы загрузить API, и просто вызвать функцию initialize() непосредственно в вашем обратном вызове ajax. (Или вытащить код из функции initialize() и просто запустить его встроенным внутри обратного вызова.)

В самом деле, в текущем коде вы уже загрузки API Карт во время загрузки страницы, с этой линией:

window.onload = loadScript; 

Это вызывает функцию loadScript(), вызываемую при загрузке страницы.

Таким образом, вы можете использовать тег <script> для загрузки API, это более или менее то же самое, что вы делаете сейчас, но проще.

Если вы хотите динамически загружать API Карт, комментарий @ sirfriday верен: ваша функция initialize не видна в глобальной области видимости, и это должно быть так, что асинхронная загрузка API может вызвать ее при ее готовности.

Вы упомянули, что «вызов инициализации не сделал этого». - но вы не должны быть вызоваinitialize() в этом случае, вы должны установить window.initialize быть ссылка на функцию, например:

window.initialize = initialize; // note no() so it doesn't call it here 

Или изменить функцию следующим образом:

window.initialize = function() { 
    ... 
}; 

А также, если вы хотите динамически загружать API, не делайте этого при onload времени. Вместо этого вызовите функцию loadScript()внутри ваш обратный вызов ajax.Это даст вам правильную последовательность операций:

  1. Page грузы
  2. Пользователь взаимодействует с ним и запрос Ajax начинается
  3. запрос
  4. Ajax завершает
  5. Maps API нагрузки
  6. Ваш initialize() функция вызывается
+1

yep - Я считаю, что вы правы, что загрузка скрипта async делает эту ненужную сложность - суперпростую демонстрацию без нее. http://jsfiddle.net/cm476qy8/1/ Спасибо за объяснение, что я получаю с помощью window.initialize! – sifriday

+0

Очевидно, что функция инициализации была проблемой. Майкл, вы предложили: '(Или вытащить код из функции initialize() и просто запустить его внутри встроенного обратного вызова.)', Который сделал трюк. Это и упрощает загрузку API-скрипта. Спасибо! – PanicBus

Смежные вопросы