Google Maps API v3 + jQuery UI选项卡出现问题

在使用Google Maps API在jQuery UI选项卡中呈现地图时,存在一些相当众所周知的问题。 我曾经见过关于类似问题的SO问题(例如这里和这里 ),但那里的解决scheme似乎只适用于Maps API的第2版。 我查阅的其他参考资料在这里和这里 ,以及我可以通过谷歌search几乎所有的东西。

我一直在试图填充一个地图( 使用API​​的v3 )到一个混合结果的jQuery选项卡。 我正在使用的最新版本的一切(目前jQuery 1.3.2,jQuery UI 1.7.2,不知道地图)。

这是标记和JavaScript:

<body> <div id="dashtabs"> <span class="logout"> <a href="go away">Log out</a> </span> <!-- tabs --> <ul class="dashtabNavigation"> <li><a href="#first_tab" >First</a></li> <li><a href="#second_tab" >Second</a></li> <li><a href="#map_tab" >Map</a></li> </ul> <!-- tab containers --> <div id="first_tab">This is my first tab</div> <div id="second_tab">This is my second tab</div> <div id="map_tab"> <div id="map_canvas"></div> </div> </div> </body> 

 $(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); } 

以下是我发现的不适用( 对于Maps API v3 ):

  • 使用jQuery UI选项卡文档中描述的左下angular技术(以及我链接的两个问题的答案)完全不起作用。 事实上,最好的代码使用CSS .ui-tabs .ui-tabs-hide { display: none; } 而不是。
  • 获取地图在标签中显示的唯一方法是将#map_canvas的CSS宽度和高度#map_canvas为绝对值。 将宽度和高度更改为auto100%导致地图根本不显示,即使它已经被成功渲染(使用绝对宽度和高度)。
  • 我无法在Maps API之外的任何地方find它,但是map.checkResize()将不再工作。 相反,您必须通过调用google.maps.event.trigger(map, 'resize')来触发resize事件。
  • 如果地图不是在绑定到tabsshow事件的函数内初始化的,地图本身的渲染是正确的,但是控件不是 – 大部分都是简单的丢失。

所以,这是我的问题:

  • 其他人有没有经历完成这个相同的壮举? 如果是这样,那么您是如何确定实际工作的,因为logging的技巧对于Maps API v3无效?
  • 根据jQuery UI文档使用Ajax加载标签内容怎么样? 我没有机会玩弄它,但我的猜测是,它将打破更多的地图。 有什么机会让它工作(或不值得尝试)?
  • 如何使地图填充最大的可能区域? 我希望它能填充标签并适应页面大小调整,就像它在maps.google.com上完成的那样。 但是,正如我所说,我似乎坚持只应用绝对的宽度和高度的CSS到地图的div。

对不起,如果这是啰嗦,但这可能是地图API v3 + jQuery选项卡的唯一文档。 干杯!

注意:这个答案收到了一个无效的第三方编辑,它基本上取代了它的内容,这是第三方编辑不应该做的。 然而,结果可能比原来更有用,所以现在给出两个版本:


  • 原作者Anon在2010年的一个版本中,经过Anon的一次编辑

    google.maps.event.trigger(地图,'resize'); map.setZoom(map.getZoom());

http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448build议作为v2的checkResize()的v3替代品。;

Blech – 糟糕的谷歌,没有cookie。


  • 用户Eugeniusz Fizdejko的完整改写forms2012:

对于我来说,添加一个标记时工作:

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

其实从上面抓我的答案。 jQueryUI网站有答案,这里是:

为什么…

…我的滑块,谷歌地图,sIFR等不能工作时,放置在隐藏(不活动)选项卡?

任何需要一些尺寸计算来初始化的组件都不能在隐藏的标签中工作,因为标签面板本身是通过display:none隐藏的,所以里面的任何元素都不会报告它们的实际宽度和高度(在大多数浏览器中为0) 。

有一个简单的解决方法。 使用左外技术隐藏非活动选项卡面板。 例如在你的样式表中,replace类select器“.ui-tabs .ui-tabs-hide”的规则

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

对于Google地图,您也可以在显示标签后调整地图大小,如下所示:

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

resizeMap()会在特定的地图上调用Google Maps的checkResize()。

只需重新定义隐藏标签的CSS类:

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

这是你可以为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 }); 

在显示标签后加载地图。

这是哈克,但它为我工作。 只需将地图iframe的url存储在iframes rel属性中,如下所示:

 <iframe width="490" height="300" rel="http://maps.google.com/maps?f=q&amp;source=s..."></iframe> 

此事件将设置iframe src属性为rel内的url。

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

这并不能回答你所有的问题,但是我已经得到了它的工作,所有其他的答案都缺less一件事情 – 当你用“resize”事件重绘地图时,你将失去地图所居中的位置。 所以你还需要用setCenter再次更新地图的中心,如果你的地图居中在一个位置。

此外,每次触发选项卡更改时都不想初始化映射,因为这样做效率不高,可能会导致额外的地理编码。 首先,您需要保存您的居中位置(可以是静态经纬度),或者如果进行地理编码,则可能看起来像这样:

 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); } }); 

然后

 $("#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! } }); 

其中“mapTab”是您的mapTab的ID,“map”是您的地图对象的var名称。

确保初始化地图的代码在初始化标签页的代码片段之前调用。

我唯一的烦恼是在地图选项卡上单击使浏览器跳转到专注于地图,它突破了jQuery在主标签容器周围放置的默认边框。 我添加了一个返回false onclick调用地图选项卡的标签来处理第一个和一个简单的border-size:0在主选项卡div来处理第二个。

所有这一切都为我工作。

祝你好运!

我已经通过每个论坛search这个答案…他们都说使用

map.checkResize()

解决scheme….没有什么似乎工作…然后我…为什么不初始化标签时显示的标签,所以我用这个

 $("#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”是我的谷歌地图v3我的选项卡的ID。

希望这对你有用!

嘿家伙,这个代码修复了错误,但在IE不工作。 经过search和search,我发现我们必须添加下面的一行,一切工作到完美:

 < !--[if IE]> < style type="text/css"> .ui-tabs .ui-tabs-hide { position: relative; } < /style> < ![endif]--> 

我也有这个问题,我通过AJAX加载地图。

似乎百分比的问题是没有任何设置大小(包含加载标记的那个)的面板。

创build标签时使用下面的代码帮了我很多:

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

你可以打电话

map.fitBounds(边界)

那将会刷新

非常恼人的问题,但有点hackaround它是可以修复的。 关键在于,当您select一个新的标签时,相对#tabs的位置将调整为每个标签的外部高度。 以下是我如何做到的:

 $('#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); } }); 

这里是我使用的CSS:

 #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} 

通过asynchronous加载API ,然后从onclick事件中的<a>标签绑定到相关选项卡,从而简单地调用loadScript ,就可以轻松实现这一function:

 <li><a href="#tab3" onclick="loadScript();">Maps</a></li> 

我有同样的问题,没有答案为我工作。 也许我不知道如何在代码中使用它们,所以我在标签菜单中添加了一个onclick事件来初始化Google地图,它正在工作。 我不知道这是不是一个好的做法。

 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); } <div id="tabs-4"> <div id="map" style="width:580px;height:380px;"> </div> </div> 

Maps API v3(exp)和jQuery UI 1.10的另一个解决scheme:

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

我做了什么基思说,它适用于我,在我的情况下,我使用jQuery航点为我的标签导航,为了更好地理解这里是我使用的代码:

在HEAD

 <head> <!-- Google Maps --> <script> function initialize() { var mapOptions = { zoom: 8, center: new google.maps.LatLng(-34.397, 150.644) }; var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); } function loadScript() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' + '&signed_in=true&callback=initialize'; document.body.appendChild(script); } window.onload = loadScript; </script> </head> 

在我的标签里面:

 <li><a href="#MyMap" onclick="loadScript();">My Map</a></li> 

然后在DIV

 <div id="map_canvas"></div> 

希望这可以帮助别人,谢谢大家!

我在Semantic UI遇到了同样的问题,调用init();时问题就解决了init(); 当一个标签加载或者你可以绑定它的function。