2011-05-08 12 views
5

Sin duda, este toca preguntas anteriores relacionadas con la visualización del mapa durante la inicialización. Sin embargo, el problema aquí es que la visualización del mapa se establece en ninguna después de que el mapa ya se haya inicializado. La última línea de mi viuda.onload establece el mapa para mostrar: ninguno; La inicialización del mapa ya debería haberse completado en ese momento, pero el hecho es que la llamada final está causando el problema.Google Maps JS v3: visualización del mapa: ninguna; después de la inicialización del mapa que causa el mapa dañado

window.onload(); función ...

window.onload = function(){ 
    changeTheme(me); // do it now so current_theme is avaible to switchTabs(); 
    switchTabs("tab3"); // sets map div visible 
    initMaps(); // map initialization. code included. 
    loadFavoritePlaces(); // asynch $getJSON call, adds markers. No matter the condition of map, markers appear in their proper locations. 
    closePopup("images"); 
    closePopup("location"); // sets maps.mini_map display: none; Problems if we loadUserTable() later. Otherwise OK. Odd! 
    closePopup("tweet"); 
    centerDiv(); 
    document.title = '@'+me.screen_name+' - PithyTwits.com'; 
    users[me.id_str] = me; 
    getPage(); // asynch $.getJSON loads tweets. Not an issue. 

    // Append a scroll event handler to tweet_div 
    $("#tweet_div").scroll(function() { 
    var pos = $(this)[0].scrollHeight - $(this).scrollTop(); 
    if(pos != prev_scroll){ // hack to prevent scroll function from firing twice 
     prev_scroll = pos; 
     if (pos == $(this).outerHeight()) { 
     $("#throbber").fadeIn(); 
     getPage(); 
     } 
    } 
    }); 

    loadUserTable(me.id_str); 
    /* loadUserTable(); calls switchTabs("tab1"); which sets map div display: none; 
    if I comment this out the map initialization completes properly, but my 'tab1' 
    doesn't get populated properly. And page doesn't start on 'tab1', which is required. */ 

// end window.onload() 
} 

initMaps(); función ...

function initMaps() { 

    // markers list 
    maps.markers = new Object; 

    // visibility status' 
    maps.markerStatus = new Object; 
    maps.markerStatus['query'] = true; 
    maps.markerStatus['tweet'] = true; 
    maps.markerStatus['favorite'] = true; 

    // define marker images 
    maps.reticleImage = new google.maps.MarkerImage('images/reticle.png', 
    new google.maps.Size(63, 63), 
    new google.maps.Point(0,0), 
    ... 
    Declarations removed to streamline post. 
    ... 
    new google.maps.Point(0,0), 
    new google.maps.Point(1, 13)); 
    maps.markerShape = { 
     type: "poly", 
     coords: [9,22,16,11,16,5,11,1,6,1,2,5,2,11,9,22] 
     } 

    // setup map options 
    var latlng = new google.maps.LatLng(39.520427, -94.770621); 
    var latlng2 = new google.maps.LatLng(46.1912, -122.1944); 
    var myOptions = { 
    zoom: 3, 
    center: latlng, 
    mapTypeId: google.maps.MapTypeId.HYBRID 
    }; 
    var myOptions2 = { 
    zoom: 13, 
    center: latlng2, 
    disableDefaultUI: true, 
    draggable: false, 
    keyboardShortcuts: false, 
    mapTypeControl: false, 
    scrollwheel: false, 
    mapTypeId: google.maps.MapTypeId.HYBRID 
    }; 

    // initialize maps 
    maps.main_map = new google.maps.Map(document.getElementById("map_div"), myOptions); 
    maps.mini_map = new google.maps.Map(document.getElementById("mini_map"), myOptions2); 

    // default map center markers 
    maps.mini_map_marker = new google.maps.Marker({ 
    position: latlng2, 
    map: maps.mini_map, 
    icon: maps.favoriteMarker, 
    shadow: maps.markerShadow, 
    }); 
    maps.reticleMarker = new google.maps.Marker({ 
    position: latlng, 
    map: maps.main_map, 
    shape: reticleShape, 
    icon: maps.reticleImage, 
    }); 

    // event handlers 
    google.maps.event.addListener(maps.main_map, 'zoom_changed', mapZoomed); 
    google.maps.event.addListener(maps.main_map, 'bounds_changed', 
     function(){maps.reticleMarker.setPosition(maps.main_map.getCenter());}); 

    //idle event listener provided by @Guan in the marked answer. 
    google.maps.event.addListenerOnce(maps.main_map, 'idle', function() { 
     var div = document.getElementById("tab3_content"); 
     div.style.display = "none"; 
     div.style.position = "relative"; 
     div.style.left = "0px"; 
    }); 

    // initialize controls 
    var controls = document.getElementById("visibility_controls"); 
    maps.main_map.controls[google.maps.ControlPosition.TOP_CENTER].push(controls); 
    controls.style.display = "inline"; 
    var controls = document.getElementById("control_controls"); 
    maps.main_map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(controls); 
    controls.style.display = "inline"; 
    var controls = document.getElementById("query_controls"); 
    maps.main_map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(controls); 
    controls.style.display = "inline"; 
} 

Si llamo loadUserTable(); al final de window.onload(); Me sale esto ... (munged)

Maps not properly initialized

Si no llamo loadUserTable(); al final de window.onload(); Me sale esto ... (correcta)

Maps properly initialized

Dado que el problema se deriva de la visualización de mapas que se establece en ninguno después de los mapas deberían haber inicializado, sería llevar a creer que el mapa de inicialización está sucediendo realmente no sincrónicamente. Entonces, ¿cómo sé cuándo está terminado y es seguro ocultar los mapas div? Y también está la pregunta de por qué el mini_map parece depender de la visibilidad del main_map, en lugar de su propia visibilidad. Obtengo los mismos resultados tanto en Chrome como en Firefox, en Linux.

Cualquier ayuda es ayuda :)

Saltar

ACTUALIZACIÓN: He cambiado la última llamada a setTimeout ("loadUserTable();", 1000); y 1 segundo es suficiente pausa para que las cosas funcionen, ¡pero no es lo que quiero! Dado que @Jobsz verifica que se trata de un problema conocido, voy a recurrir a la inicialización fuera de la pantalla y mover el mapa a su posición cuando sea necesario para visualizarlo, o esconderlo y ponerlo en posición después de un corto tiempo de espera.

SOLUCIÓN: proporcionados por @Guan (respuesta cuadros)

que no querían el mapa visible durante la inicialización. Pero quería que se inicializara y estuviera listo cuando el usuario eligiera esa pestaña.

El mapa div se establece inicialmente por lo tanto ...

id="tab3_content" style="display: block;position: absolute; left: -1000px;" 

Eso hace que sea visible, pero fuera de la pantalla hacia la izquierda.

y luego ponga un detector para el evento de inactividad en el mapa de inicialización ...

google.maps.event.addListenerOnce(maps.main_map, 'idle', function() { 
    var div = document.getElementById("tab3_content"); 
    div.style.display = "none"; 
    div.style.position = "relative"; 
    div.style.left = "0px"; 
}); 

que los incendios de eventos una vez cuando el mapa está inactivo (listo). Oculta el div y lo mueve a su posición en la pantalla.

La función loadUserTable() se llama en el flujo de programa normal y la vida es buena. :)

+0

Sí, la inicialización fuera de pantalla fue algo que originalmente estaba considerando también. ¿Funciona bien para ti? – Atticus

Respuesta

8
google.maps.event.addListenerOnce(map, 'idle', function() { 
    $('#addstop').css({ 
     display: 'none', 
     left: '0', 
     top: '0' 
    }); 
}); 

Este evento ocurre sólo una vez después de que el mapa se ha cargado completamente y 'inactivo'

+0

¡Eso parece una cosa poderosa! Han pasado 8 meses. Tengo que volver a buscar mi código. Hasta el voto por ahora ... si hace lo que parece, moveré el cheque. La pantalla tiene su ventaja, pero la esencia de la pregunta era "¿Cómo puedo saber cuándo está listo el mapa?". Esto responde eso. No sabía sobre el evento 'inactivo'. ¿Debería poder también configurar un oyente simple para inactivo y luego desarmarlo en el primer golpe? De todos modos, gracias! – BentFX

+0

Eso lo hace. Gracias. Su primera respuesta StackOverflow es un ganador. Sigue así :) Aún me inicializo fuera de la pantalla, pero esto dispara y mueve el div cuando está listo. – BentFX

+0

@BentFX Considere también el evento 'tilesloaded' si desea saber cuándo todo se ha detenido. [Referencia] (https://developers.google.com/maps/documentation/javascript/reference#Map) – hitautodestruct

2

Sí, tuve este mismo problema.

Lo que hice fue activar la inicialización después de hacer clic en el botón de evento que muestra el mapa oculto.

Así que tengo un div oculto, cuando se hace clic para mostrarlo, lo visualizo y luego lo inicializo. ¿Es esto factible para lo que estás tratando de lograr? Supongo que desea rendimiento en el sentido de que prefiere el clic para mostrar instantáneamente un mapa poblado; sin embargo, no es demasiado lento para poblar el área pequeña que está atando si lo hace en el evento de clic.

+0

Gracias @Jobsz por la respuesta rápida. A veces la respuesta correcta es "He estado allí, hecho eso, ¡lucha con eso!" El setTimeout(); me demuestra que solo es cuestión de darle tiempo para que funcione. ¡Tendrá que funcionar fuera de la pantalla! Todavía existe la confusión de por qué la visualización main_map corrompe el mini_map? ¡Impar! A menos que alguien pueda exponer una devolución de llamada completa de inicialización, usted tiene la respuesta final. – BentFX

+0

Sí, me gustaría saber el problema con los divs ocultos también ... Hice una buena cantidad de búsquedas sobre este tema yo mismo sin suerte. Definitivamente podría hacer un setTimeout y tener un icono de carga durante la duración para miradas. pero sí, mi sugerencia es inicializar al alternar. Me mapeé en un conjunto de datos si el mapa ya se ha inicializado para evitar que se vuelva a hacer el trabajo. Podría ser algo que quieras hacer también si estás tratando con múltiples mapas de vista previa, que creo que eres. – Atticus

+0

Vista previa de mapas ??? No, el mini_map solo muestra acercamiento, y detalles para los marcadores seleccionados, y cuando coloca el ícono de ubicación en un tweet. Mi próximo obstáculo es implementar una función similar en una ventana de información para los marcadores seleccionados, y dejar el diálogo mini_map para las ubicaciones en los tweets. – BentFX

15

Podría intentar llamar

//map hold's a reference to your current map 
google.maps.event.trigger(map, 'resize'); 

Después el mapa/div que contiene se hace visible?

+0

Función impresionante. Definitivamente vale la pena votar. Tuve que deshacer mi código para recrear el problema, solo para ver el trabajo de "redimensionamiento". Lo endereza todo. Por ahora estoy inicializando fuera de la pantalla, pero voy a pegar esto en un comentario en mi inicialización por si acaso lo necesito después. ¡Gracias! – BentFX

+1

La desventaja que veo al usar el evento de cambio de tamaño como parte de la visualización inicial ... Si el mapa se inicializa oculto, parece tratarse como un mapa de 0x0 con el centro en la esquina superior izquierda. Luego, cuando activa el evento de cambio de tamaño, se da cuenta de los nuevos límites, sin mover la esquina superior izquierda, y pierde su centro de mapa inicial. – BentFX

0

Sólo esto puede ayudarle.

Acabo de tener una aplicación que usa pestañas mezcladas con gmap divs.

Me solucionaron los mismos problemas. La consola solo muestra un mensaje de imagen de corrupción. ¡Tus ideas ayudan mucho!

sólo tiene que utilizar este

$("#tab-3").click(function(){ 

$(".tab-3").removeClass("ui-screen-hidden"); 

$(".tab-1").addClass("ui-screen-hidden"); 

$(".tab-2").addClass("ui-screen-hidden"); 

initializedonationlocation(); 


}) 

    function initializedonationlocationdr() { 
    var directionsDisplay = new google.maps.DirectionsRenderer(); 
    geocoder2 = new google.maps.Geocoder(); 
    infowindow2 = new google.maps.InfoWindow(); 
    var myOptions = { 
     zoom: 10, 
     center: new google.maps.LatLng(38.7,-121.59), 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 



    var map2 = new google.maps.Map(document.getElementById('my_map_donation_donationreceipt'), 
     myOptions); 

    google.maps.event.addListener(map2, 'click', function(e) { 

    geocoder.geocode(
      {'latLng': e.latLng}, 
      function(results, status) { 
      if (status == google.maps.GeocoderStatus.OK) { 
       if (results[0]) { 
       if (marker2) { 
        marker2.setPosition(e.latLng); 
       } else { 
        marker2 = new google.maps.Marker({ 
        position: e.latLng, 
        map: map2}); 
       } 
       infowindow2.setContent(results[0].formatted_address); 


       var postCode = extractFromAdress(results[0].address_components, "postal_code"); 
       var street = extractFromAdress(results[0].address_components, "route"); 
       var town = extractFromAdress(results[0].address_components, "locality"); 
       var country = extractFromAdress(results[0].address_components, "country"); 
       var state = extractFromAdress(results[0].address_components, "administrative_area_level_1"); 

       $("#city_donationdr").val(town); 
       $("#state_donationdr").val(state); 
       $("#zip_donationdr").val(postCode); 
       $("#address_donationdr").val(street); 
       infowindow2.open(map2, marker2); 

       // Changing window 

       var prevSelection3 = $("#tabmap").val(); 
        var newSelection3 = $("#navbar2 ul li").children("a").attr("data-tab-class"); 
        $("."+prevSelection3).addClass("ui-screen-hidden"); 
        $("."+newSelection3).removeClass("ui-screen-hidden"); 
        prevSelection3 = newSelection3; 
        $("#tabmap").val(prevSelection3); 


       document.getElementById('geocoding').innerHTML = ""; 
       $("#coords_donationdr").val(e.latLng); 
       $("#address_donationdr").focus(); 
       GetCurbSideCoordsDR(directionsDisplay,map2); 
       } else { 
       document.getElementById('geocoding').innerHTML = 
        'No results found'; 
       } 
      } else { 
       document.getElementById('geocoding').innerHTML = 
        'Geocoder failed due to: ' + status; 
      } 
      }); 

    }); 

    } 

Sólo llamada de inicialización sólo cuando pestaña que contiene gmap se mostró. No antes. Muchos foros muestran la inicialización de gmap en la carga de páginas. En combinación con pestañas, solo llame a la inicialización después de que aparezca la pestaña.

Cuestiones relacionadas