Problemas con Google Maps API v3 + jQuery UI Tabs

Hay una serie de problemas, que parecen ser bastante conocidos, cuando se utiliza la API de Google Maps para representar un mapa dentro de la pestaña de la interfaz de usuario de jQuery. He visto publicaciones de SO sobre problemas similares ( aquí y aquí , por ejemplo), pero las soluciones parecen funcionar solo para v2 de la API de Google Maps. Otras referencias que revisé están aquí y aquí , junto con casi todo lo que pude encontrar a través de Google.

He intentado rellenar un mapa ( usando la v3 de la API ) en una pestaña jQuery con resultados mixtos. Estoy usando las últimas versiones de todo (actualmente jQuery 1.3.2, jQuery UI 1.7.2, no sé sobre Maps).

Este es el marcado y javascript:

 
Log out
This is my first tab
This is my second tab

y

 $(document).ready(function() { var map = null; $('#dashtabs').tabs(); $('#dashtabs').bind('tabsshow', function(event, ui) { if (ui.panel.id == 'map_tab' && !map) { map = initializeMap(); google.maps.event.trigger(map, 'resize'); } }); }); function initializeMap() { // Just some canned map for now var latlng = new google.maps.LatLng(-34.397, 150.644); var myOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; return new google.maps.Map($('#map_canvas')[0], myOptions); } 

Y esto es lo que he encontrado que funciona / no funciona ( para Maps API v3 ):

  • Usar la técnica de la izquierda como se describe en la documentación de jQuery UI Tabs (y en las respuestas a las dos preguntas que he vinculado) no funciona en absoluto. De hecho, el código que mejor funciona usa CSS .ui-tabs .ui-tabs-hide { display: none; } .ui-tabs .ui-tabs-hide { display: none; } cambio.
  • La única forma de hacer que un mapa se muestre en una pestaña es configurar el ancho y el alto CSS de #map_canvas como valores absolutos. Cambiar el ancho y alto a auto o al 100% hace que el mapa no se muestre en absoluto, incluso si ya se ha procesado correctamente (usando ancho y alto absolutos).
  • No pude encontrarlo documentado en ningún lugar fuera de la API de Maps, pero map.checkResize() ya no funcionará. En su lugar, debe iniciar un evento de cambio de tamaño llamando a google.maps.event.trigger(map, 'resize') .
  • Si el mapa no se inicializa dentro de una función vinculada a un evento tabsshow , el mapa en sí se representa correctamente, pero los controles no son: la mayoría simplemente faltan.

Asi que aqui están mis preguntas:

  • ¿Alguien más tiene experiencia en lograr esta misma hazaña? Si es así, ¿cómo averiguaste qué funcionaría realmente, ya que los trucos documentados no funcionan para Maps API v3?
  • ¿Qué hay sobre cargar contenido de tabs usando Ajax según los documentos jQuery UI ? No he tenido la oportunidad de jugar con eso, pero creo que va a romper aún más los mapas. ¿Cuáles son las posibilidades de que funcione (o no vale la pena intentarlo)?
  • ¿Cómo hago que el mapa llene el área más grande posible? Me gustaría llenar la pestaña y adaptarme al tamaño de la página, de la misma forma en que se hace en maps.google.com. Pero, como dije, parece que estoy atascado con la aplicación de CSS de ancho y alto absolutos al div del mapa.

Lo sentimos si esto fue largo, pero esta podría ser la única documentación para las tabs de Maps API v3 + jQuery. ¡Aclamaciones!

    Nota: esta respuesta recibió una edición de terceros no válida que esencialmente reemplazó su contenido, algo que un editor de terceros no debería hacer. Sin embargo, el resultado puede ser más útil que el original, por lo que ambas versiones se dan a continuación:


    • Versión del autor original Anon de 2010, después de una edición de Anon

      google.maps.event.trigger (map, ‘resize’); map.setZoom (map.getZoom ());

    es sugerido por http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448 como un sustituto de v3 para v2’s checkResize ().

    Blech – Google mal, sin cookies.


    • Formulario completo de reescritura 2012 del usuario Eugeniusz Fizdejko:

    Para mí funciona cuando agrego un marcador:

     var marker = new google.maps.Marker({ position: myLatlng, title:"Hello World!" }); google.maps.event.addListener(map, "idle", function(){ marker.setMap(map); }); 

    En realidad, rayar mi respuesta anterior. El sitio web jQueryUI tiene la respuesta y aquí está:

    Por que…

    … mi control deslizante, Google Map, sIFR etc. no funcionan cuando se colocan en una pestaña oculta (inactiva)?

    Cualquier componente que requiera algún cálculo dimensional para su inicialización no funcionará en una pestaña oculta, porque el panel de tabs está oculto a través de la pantalla: ninguno para que ningún elemento dentro informe su ancho y alto real (0 en la mayoría de los navegadores) .

    Hay una solución fácil. Use la técnica de la izquierda para ocultar paneles de tabs inactivos. Por ejemplo, en la hoja de estilos, reemplace la regla del selector de clases “.ui-tabs .ui-tabs-hide” con

     .ui-tabs .ui-tabs-hide { position: absolute; left: -10000px; } 

    Para los mapas de Google también puede cambiar el tamaño del mapa una vez que la pestaña se muestra así:

     $('#example').bind('tabsshow', function(event, ui) { if (ui.panel.id == "map-tab") { resizeMap(); } }); 

    resizeMap () llamará a checkResize () de Google Maps en el mapa en particular.

    Simplemente redefina la clase CSS para la pestaña oculta:

     .ui-tabs .ui-tabs-hide { position: absolute !important; left: -10000px !important; display:block !important; } 

    Esto es lo que puedes hacer por Google Maps v3:

     google.maps.event.addListenerOnce(map, 'idle', function() { google.maps.event.trigger(map, 'resize'); map.setCenter(point); // be sure to reset the map center as well }); 

    Cargué los mapas después de que se haya mostrado la pestaña.

    Esto es raro pero funcionó para mí. Simplemente almacene la url del mapa iframe dentro del atributo rel de iframes así:

      

    Este evento establecerá el atributo ifrme src en la url dentro del rel.

      $("#tabs").tabs({ show:function(event, ui) { var rel = $(ui.panel).find('iframe').attr('rel'); $(ui.panel).find('iframe').attr('src',rel); } }); 

    Esto no responde a todas sus preguntas, pero lo he hecho funcionar y a todas las otras respuestas les falta una cosa: cuando vuelva a dibujar el mapa con el evento de “cambio de tamaño”, perderá el lugar en el que se centró el mapa. Entonces también necesita actualizar el centro del mapa nuevamente con setCenter , si su mapa está centrado en una posición.

    Además, no desea inicializar el mapa cada vez que se activa el cambio de pestaña, ya que no es eficiente y puede generar códigos geográficos adicionales. En primer lugar, debe guardar su ubicación centrada, que puede ser una latitud / longitud estática, o si la geoencoding puede tener un aspecto similar a este:

     var address = "21 Jump St, New York, NY"; var geocoder = new google.maps.Geocoder(); var myOptions = { zoom: 16, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var center; geocoder.geocode( { 'address': address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { center = results[0].geometry.location; map.setCenter(center); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert("Geocode was not successful for the following reason: " + status); } }); 

    Entonces

     $("#tabs").tabs(); $('#tabs').bind('tabsshow', function(event, ui) { if (ui.panel.id == "mapTab") { google.maps.event.trigger(map, "resize"); map.setCenter(center); // Important to add this! } }); 

    Donde ‘mapTab’ es la ID de su mapTab, y ‘map’ es el nombre var para su objeto de mapa.

    Asegúrese de que el código que inicializa su mapa se llame ANTES del fragmento que inicializa sus tabs.

    Las únicas molestias que tuve fueron que un clic en la pestaña del mapa hizo que el navegador saltara para enfocarse en el mapa y que rompiera el borde predeterminado que jQuery coloca alrededor del contenedor de las tabs principales. Agregué una llamada de retorno de llamada falsa a la etiqueta de la pestaña del mapa para manejar el primero y un tamaño de borde simple: 0 en el divisor de tabs principal para manejar el segundo.

    Todo esto funcionó para mí.

    ¡Buena suerte!

    He estado en todos los foros buscando la respuesta a esto … todos dijeron usar el

    map.checkResize()

    solución … nada parecía funcionar … entonces yo … ¿por qué no inicializar la pestaña cuando se muestra la pestaña, así que usé esto

     $("#servicesSlider ").tabs({ //event: 'mouseover' fx: { height: 'toggle', opacity: 'toggle'}, show: function(event, ui) { if (ui.panel.id == "service5") { $(ui.panel).css("height","100%") initialize() }} }); 

    “service5” es el id de mi pestaña que contiene mi google map v3.

    ¡Espero que esto funcione para usted!

    Hola chicos, este código corrige el error, pero en IE no funciona. Después de buscar y buscar, descubrí que debemos agregar la siguiente línea y todo funciona a la perfección:

      

    También tuve este problema, estaba cargando los mapas a través de AJAX.

    Parece que el problema con el porcentaje tenía que ver con que el panel no tenía ningún tamaño establecido (el que contenía el marcado cargado).

    Usar el siguiente código al crear las tabs me ayudó mucho:

     $("#mainTabs").tabs({'show': function(event, ui){ $(ui.panel).attr('style', 'width:100%;height:100%;'); return true; }}); 

    Puedes llamar

    map.fitBounds (límites)

    eso hará la actualización

    Problema muy irritante pero con un poco de dificultad es reparable. La clave es hacer que las tags relativas de posición se ajusten a la altura exterior de cada una de las tabs cuando selecciona una nueva. Así es como lo hice:

     $('#tabs').tabs({ selected:0, 'select': function(event, ui) { //this is the href of the tab you're selecting var currentTab = $(ui.tab).attr('href'); //this is the height of the related tab plus a figure on the end to account for padding... var currentInner = $(currentTab + '.detail-tab').outerHeight() + 40; //now just apply the height of the current tab you're selecting to the entire position:relative #tabs ID $('#tabs').css('height', currentInner); } }); 

    aquí está el CSS que usé:

     #tabs { position: relative; } /*set the width here to whatever your column width is*/ .ui-tabs-panel{ position:absolute;top:0px; left:0; width:575px;} .ui-tabs-panel.ui-tabs-hide { display:block !important; position:absolute; left:-99999em; top:-9999em} 

    Lo conseguí fácilmente cargando Asincrónicamente la API y luego simplemente llamando a loadScript desde la etiqueta vinculada a la pestaña relevante del evento onclick como así:

     
  • Maps
  • Tuve el mismo problema y ninguna de las respuestas funcionó para mí. Tal vez no sabía cómo usarlos en mi código, así que agregué un evento onclick al menú de tabs para inicializar el mapa de Google y está funcionando. No sé si es una buena práctica.

     jQuery(document).ready(function($) { $( '#tabs' ).tabs(); var href = $('#tabs').find('a[href="#tabs-4"]'); (href).on('click',function(){ initialize(); })}); var map; function initialize() { var mapOptions = { zoom: 8, center: new google.maps.LatLng(-34.397, 150.644), mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map'), mapOptions); } 

    Otra solución para Maps API v3 (exp) y jQuery UI 1.10:

     var pano = new google.maps.StreetViewPanotwig(...); $('#tabs').tabs({ 'activate': function(event, ui) { if (ui.newPanel[0].id == "maps-tabs-id") { pano.setVisible(true); } } }); 

    Hice lo que dice Keith y me funciona, en mi caso estoy usando jQuery waypoints para mi navegación con tabs, para una mejor comprensión aquí está el código que utilicé:

    En la cabeza

         

    Dentro de mis tabs:

     
  • My Map
  • Luego en el DIV

     

    Espero que esto ayude a alguien, gracias por todo!

    Estaba enfrentando el mismo problema en Semantic UI , el problema se solucionó al llamar a init(); función cuando se carga una pestaña o puede vincularlo también.