Jquery Mobile не загружает Google Map (кроме обновления) - PullRequest
9 голосов
/ 10 февраля 2012

Я использую Jquery Mobile 1.0 и Google Maps v3 для загрузки карты местоположения пользователя. Карта загружается нормально при доступе по прямой ссылке, но при обращении по ссылке она захлебывается и ничего не отображается. Если я обновлю страницу, карта загрузится нормально.

Вот ссылка на тестовую сборку, которая имитирует проблему: http://stacefelder.com/stacefelder/Tests/index.html нажмите «Моя карта», чтобы увидеть ... ничего. Нажмите обновить, чтобы увидеть карту загрузки.

Вот скрипт в заголовке страницы карты:

<script type="text/javascript">
    $('#basic_map').live("pageshow", function() {
        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position){
                initialize(position.coords.latitude,position.coords.longitude);
            });
        }
    });
    function initialize(lat,lng) {
        var latlng = new google.maps.LatLng(lat, lng);
        var myOptions = {
            zoom: 8,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
    }
</script>

А вот HTML-код в теле страницы карты:

<div data-role="page" id="basic_map">

    <div data-role="header">
        <h1>map test 901</h1>
    </div>
    <div id="map_canvas"></div>
</div>

Я также попробовал pagecreate вместо pageshow без заметной разницы. Есть идеи, что мне здесь не хватает? Спасибо за любые предложения!

Ответы [ 6 ]

14 голосов
/ 10 февраля 2012

Если вы переходите на эту страницу с другой страницы, jQM извлекает JS только из ваших тегов div [data-role = "page"], поэтому, если ваш JS находится в ваших <head> тегах, которые не будут извлеченыв, это то, что вызывает ваши проблемы.

Также да, вы должны использовать pageinit вместо pagehow, pagehow будет перезапущено, если вы вернетесь к странице и т. д. ... если у вас возникнут проблемы сзагрузив несколько раз и несколько страниц с одним и тем же идентификатором, есть хитрый трюк, чтобы использовать последний div [data-role = "page"]

jQuery("div:jqmData(role='page'):last").bind('pageinit', function(){

Так что для беспроблемного ответа попробуйте это:

<div data-role="page" id="basic_map">
    <script type="text/javascript">
        $("div:jqmData(role='page'):last").bind('pageinit', function() {
            if(navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function(position){
                    initialize(position.coords.latitude,position.coords.longitude);
                });
            }
        });
        function initialize(lat,lng) {
            var latlng = new google.maps.LatLng(lat, lng);
            var myOptions = {
                zoom: 8,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
        }
    </script>
    <div data-role="header">
        <h1>map test 901</h1>
    </div>
    <div id="map_canvas"></div>
</div>
4 голосов
/ 20 февраля 2012

Я столкнулся с той же проблемой и не смог исправить ее с помощью модели события JQM.

Наконец я исправил ее, добавив rel="external" ко всем якорям, которые ссылаются на страницу с картой Google.Это решение деактивирует переходы страниц и предварительные загрузчики.

Быстро и грязно, но ... оно работает сейчас.

3 голосов
/ 10 февраля 2012

Я бы предложил использовать событие pageinit вместо:

Из документов jQuery:

http://jquerymobile.com/demos/1.0.1/docs/api/events.html

pageinit

Инициируется на инициализируемой странице,после инициализации происходит.Мы рекомендуем связываться с этим событием вместо DOM ready (), потому что это будет работать независимо от того, загружается ли страница напрямую или содержимое перетаскивается на другую страницу как часть системы навигации Ajax.

$( '#aboutPage' ).live( 'pageinit',function(event){
  alert( 'This page was just enhanced by jQuery Mobile!' );
});
2 голосов
/ 03 мая 2012

У меня была похожая проблема, и я использую внешний файл js.

Несколько вещей, которые я сделал неправильно:

  • Нужно использовать pageinit вместо готового документа jquery
  • У меня была проверка класса, чтобы увидеть, если <body class="map", прежде чем запустить загрузку моей карты, но она должна быть на уровне div-страницы JQM, как <div data-role="page" class="page-map">, так как, если страница загружается через Ajax, класс body не будет иметь значения.
  • Мне нужно получить правильный холст карты, поэтому в конце я задаю class="map_canvas" вместо id="map_canvas", чтобы избежать дублирования идентификатора.
  • Затем мне нужно узнать текущую активную страницу поделает activePage = $(event.target).С этим я могу получить правильный холст по $('.map_canvas', activePage).(Однажды я столкнулся с тем, что карта загружена в некоторый скрытый div)
  • Поскольку я использую внешний файл js, все соответствующие файлы js должны быть включены в каждую страницу JQM.Я поместил их в файл макета, который используют все страницы JQM.

Мой код (coffeescript):

$(document).on "pageinit", (event) ->
  activePage = $(event.target)
  return if !$(activePage).is('.page-map')

  createMap = (options) ->
    canvas = $('.map_canvas', activePage)
    canvas.css(width: '100%', height: '90%')
    map = new google.maps.Map(canvas[0], options)

  address = $('.address', activePage).text()
  geocoder = new google.maps.Geocoder()

  geocoder.geocode {address: address}, (results, status) ->
    if status == google.maps.GeocoderStatus.OK
      options =
        zoom: 14
        center: results[0].geometry.location
        mapTypeId: google.maps.MapTypeId.ROADMAP

      map = createMap(options)
      map.setCenter(results[0].geometry.location)
1 голос
/ 28 августа 2013

Удивительный ответ Лулалала - спасибо за решение моей проблемы.Я изменил код HTML (class = "gmap_canvas" вместо id = "gmap_canvas") в соответствии с его ответом.Кроме того, я добавил

google.maps.event.trigger (map, "resize");

, чтобы правильно отобразить карту.

Подробнее см. Также функцию showMap.

В html я изменил тег div для карты на:

<div data-role="content">
 <div id="container" class="container">
  <div class="gmap_canvas"></div>       
 </div>
</div><!-- div content -->

и добавил rel = "external"- Атрибут для всех тегов привязки:

<div data-role="navbar" data-theme="b">
<ul>
<li><a id="karteLink"   href="index.html" data-icon="karte" data-transition="fade" rel="external">KARTE</a></li>
<li><a id="listeLink"   href="liste.html" data-icon="liste" data-transition="fade" rel="external">LISTE</a></li>                    
<li><a id="optionsLink" href="favoriten.html"   data-icon="options"     data-transition="fade" rel="external">OPTIONEN</a></li>
</ul>
</div><!-- /navbar   --> 

Мой код (jquery)

    var activePage;

        $( '#karte' ).live( 'pageinit',function(event){
            activePage = $(event.target);
            initialize();
        });

        function initialize() {
            // prepare Geocoder   
            clearOverlays(); 
            var geocoder = new google.maps.Geocoder();
            navigator.geolocation.getCurrentPosition(function(position) {
                var myLatlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                var myOptions = { // default map options
                    zoom: 12,
                    center: myLatlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                showMap(myOptions);
                google.maps.event.trigger(map, "resize");
                findPlaces();
            });
        }


        function showMap( options ) {
            canvas = $('.gmap_canvas', activePage);
            canvas.css({width: '100%', height: '100%', position: 'relative'});
            map = new google.maps.Map(canvas[0], options);
            myLatLng = options.center;
        }

    // clear overlays function
    function clearOverlays() {
        if (markers) {
            for (i in markers) {
                markers[i].setMap(null);
            }
            markers = [];
            infos = [];
        }
    }

    // clear infos function
    function clearInfos() {
        if (infos) {
            for (i in infos) {
                if (infos[i].getMap()) {
                    infos[i].close();
                }
            }
        }
    }

    // find custom places function
    function findPlaces() {
        var cur_location = myLatLng;
        // prepare request to Places
        var request = {
            location: cur_location,
            radius: radius,
            type: [type],
            keyword: [keyword]
        };
        // send request
        service = new google.maps.places.PlacesService(map);
        service.search(request, createMarkers);
    }

// create markers (from 'findPlaces' function)
function createMarkers(results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        // if we have found something - clear map (overlays)
        //Eigene Winzer von der Datenbannk holen

        $.getJSON(urlInit, function(data){      
            $.each(data.winzer, function(restaurant, daten){
                var locationObject = new Object;
                locationObject.name = daten.name;
                locationObject.geometry = new Object;
                locationObject.geometry.location = new google.maps.LatLng(daten.latitude,daten.longitude);
                locationObject.vicinity = daten.ort;
                createMark(locationObject);
            }); 
        });

        // and create new markers by search result
        for (var i = 0; i < results.length; i++) {
            createMark(results[i]);
        }
    } else if (status == google.maps.places.PlacesServiceStatus.ZERO_RESULTS) {
        alert('Sorry, nothing is found');
    }
}

// creare single marker function
function createMark(obj) {

    // prepare new Marker object
    var mark = new google.maps.Marker({
        position: obj.geometry.location,
        map: map,
        title: obj.name,
        animation: google.maps.Animation.DROP
    });
    markers.push(mark);

    // prepare info window
    var infowindow = new google.maps.InfoWindow({
        content: '<img src="' + obj.icon + '" /><font style="color:#000;">' + obj.name + 
        '<br />Rating: ' + obj.rating + '<br />Vicinity: ' + obj.vicinity + '</font>'
    });


    // add event handler to current marker
    google.maps.event.addListener(mark, 'click', function() {
        clearInfos();
        infowindow.open(map,mark);
    });
    infos.push(infowindow);
}
0 голосов
/ 22 мая 2014

Интересно, мне нужно использовать "pageshow" вместо "pageinit" при переходе с другой страницы.

При использовании "pageinit" функция on запускается, а функция обратного вызова для рисования карты - нет.При использовании "pageshow", как в $( document ).on( "pageshow", "#map-page", function() {, карта отрисовки обратного вызова прекрасно запускается jQuery.

Так что, хотя я бы предпочел использовать "pageinit", у меня это просто не работает.

...