Google Maps API v3 + jQuery UI 标签的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1428178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Problems with Google Maps API v3 + jQuery UI Tabs
提问by Matt Ball
There are a number of problems, which seem to be fairly well-known, when using the Google Maps API to render a map within a jQuery UI tab. I've seen SO questions posted about similar issues (hereand here, for example) but the solutions there only seem to work for v2 of the Maps API. Other references I checked out are hereand here, along with pretty much everything I could dig up through Googling.
在使用 Google Maps API 在 jQuery UI 选项卡中呈现地图时,存在许多问题,这些问题似乎是众所周知的。我已经看到有关类似问题的 SO 问题(例如,here和here),但那里的解决方案似乎只适用于 Maps API 的 v2。我检查的其他参考资料在这里和这里,以及我可以通过谷歌搜索挖掘的几乎所有内容。
I've been trying to stuff a map (using v3 of the API) into a jQuery tab with mixed results. I'm using the latest versions of everything (currently jQuery 1.3.2, jQuery UI 1.7.2, don't know about Maps).
我一直在尝试将地图(使用 API 的 v3)填充到具有混合结果的 jQuery 选项卡中。我正在使用所有东西的最新版本(目前是 jQuery 1.3.2,jQuery UI 1.7.2,不知道地图)。
This is the markup & javascript:
这是标记和 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>
and
和
$(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);
}
And here's what I've found that does/doesn't work (for Maps API v3):
这是我发现的/不工作的(对于 Maps API v3):
- Using the off-left technique as described in the jQuery UI Tabs documentation (and in the answers to the two questions I linked) doesn't work at all. In fact, the best-functioning code uses the CSS
.ui-tabs .ui-tabs-hide { display: none; }
instead. - The only way to get a map to display in a tab at all is to set the CSS width and height of
#map_canvas
to be absolute values. Changing the width and height toauto
or100%
causes the map to not display at all, even if it's already been successfully rendered (using absolute width and height). - I couldn't find it documented anywhere outside of the Maps API, but
map.checkResize()
won't work anymore. Instead, you have to fire a resize event by callinggoogle.maps.event.trigger(map, 'resize')
. - If the map is not initialized inside of a function bound to a
tabsshow
event, the map itself is rendered correctly but the controls are not - most are just plain missing.
- 使用 jQuery UI Tabs 文档(以及我链接的两个问题的答案)中描述的偏左技术根本不起作用。事实上,功能最好的代码使用 CSS
.ui-tabs .ui-tabs-hide { display: none; }
代替。 - 让地图在选项卡中显示的唯一方法是将 CSS 的宽度和高度设置
#map_canvas
为绝对值。将宽度和高度更改为auto
或100%
导致地图根本不显示,即使它已经成功渲染(使用绝对宽度和高度)。 - 我在 Maps API 之外的任何地方都找不到它的记录,但
map.checkResize()
不再起作用。相反,您必须通过调用 来触发调整大小事件google.maps.event.trigger(map, 'resize')
。 - 如果地图未在绑定到
tabsshow
事件的函数内初始化,则地图本身会正确呈现,但控件却没有 - 大多数只是明显缺失。
So, here are my questions:
所以,这里是我的问题:
- Does anyone else have experience accomplishing this same feat? If so, how did you figure out what would actually work, since the documented tricks don't work for Maps API v3?
- What about loading tab content using Ajax as per the jQuery UI docs? I haven't had a chance to play around with it but my guess is that it's going to break Maps even more. What are the chances of getting it to work (or is it not worth trying)?
- How do I make the map fill the largest possible area? I'd like it to fill the tab and adapt to page resizes, much in the way that it's done over at maps.google.com. But, as I said, I appear to be stuck with applying only absolute width and height CSS to the map div.
- 有没有其他人有完成同样壮举的经验?如果是这样,您是如何确定实际工作的,因为记录的技巧不适用于 Maps API v3?
- 根据jQuery UI 文档使用 Ajax 加载选项卡内容怎么样?我还没有机会玩它,但我的猜测是它会破坏地图更多。让它工作的机会有多大(或者不值得尝试)?
- 如何使地图填充尽可能大的区域?我希望它可以填充选项卡并适应页面大小调整,就像在 maps.google.com 上完成的那样。但是,正如我所说,我似乎坚持只将绝对宽度和高度 CSS 应用于地图 div。
Sorry if this was long-winded but this might be the only documentation for Maps API v3 + jQuery tabs. Cheers!
抱歉,如果这是冗长的,但这可能是 Maps API v3 + jQuery 选项卡的唯一文档。干杯!
回答by Anon
Note: this answer received an invalid 3rd party edit which essentially replaced its content, something that a 3rd party editor should not do. However, the result may be more useful than the original, so both versions are now given below:
注意:这个答案收到了一个无效的 3rd 方编辑,它基本上替换了它的内容,这是 3rd 方编辑不应该做的。然而,结果可能比原来的更有用,所以现在给出两个版本:
Original author Anon's version from 2010, after one edit by Anon
google.maps.event.trigger(map, 'resize'); map.setZoom( map.getZoom() );
原作者 Anon 于 2010 年的版本,经过 Anon 的一次编辑
google.maps.event.trigger(map, 'resize'); map.setZoom(map.getZoom());
is suggested by http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448as a v3 substitute for v2's checkResize().
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448建议 将 v3 替代为 v2 的 checkResize()。
Blech - bad google, no cookie.
Blech - 糟糕的谷歌,没有 cookie。
- User Eugeniusz Fizdejko's complete rewrite form 2012:
- 用户 Eugeniusz Fizdejko 的完整重写表 2012:
For me works when adding a marker:
对我来说,添加标记时有效:
var marker = new google.maps.Marker({
position: myLatlng,
title:"Hello World!"
});
google.maps.event.addListener(map, "idle", function(){
marker.setMap(map);
});
回答by jeffkee
Actually scratch my answer above. The jQueryUI website has the answer and here it is:
实际上在上面划掉我的答案。jQueryUI 网站有答案,这里是:
Why does...
...my slider, Google Map, sIFR etc. not work when placed in a hidden (inactive) tab?
Any component that requires some dimensional computation for its initialization won't work in a hidden tab, because the tab panel itself is hidden via display: none so that any elements inside won't report their actual width and height (0 in most browsers).
There's an easy workaround. Use the off-left technique for hiding inactive tab panels. E.g. in your style sheet replace the rule for the class selector ".ui-tabs .ui-tabs-hide" with
为什么...
...我的滑块、谷歌地图、sIFR 等在放置在隐藏(非活动)选项卡中时不起作用?
任何需要一些维度计算来初始化的组件都不能在隐藏选项卡中工作,因为选项卡面板本身是通过 display: none 隐藏的,所以里面的任何元素都不会报告它们的实际宽度和高度(在大多数浏览器中为 0) .
有一个简单的解决方法。使用 off-left 技术隐藏非活动选项卡面板。例如,在您的样式表中,将类选择器“.ui-tabs .ui-tabs-hide”的规则替换为
.ui-tabs .ui-tabs-hide {
position: absolute;
left: -10000px;
}
For Google maps you can also resize the map once the tab is displayed like this:
对于 Google 地图,您还可以在选项卡显示时调整地图大小,如下所示:
$('#example').bind('tabsshow', function(event, ui) {
if (ui.panel.id == "map-tab") {
resizeMap();
}
});
resizeMap() will call Google Maps' checkResize() on the particular map.
resizeMap() 将在特定地图上调用 Google 地图的 checkResize()。
回答by memberyh
Just redefine the css class for hidden tab:
只需重新定义隐藏选项卡的 css 类:
.ui-tabs .ui-tabs-hide {
position: absolute !important;
left: -10000px !important;
display:block !important;
}
回答by jayarjo
This is what you can do for Google Maps v3:
您可以为 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
});
回答by paul
This doesn't answer all your questions, but I've gotten it working and all the other answers are missing one thing -- when you redraw the map with the "resize" event, you will lose the place the map was centered on. So you also need to update the center of the map again with setCenter, if your map is centered on a position.
这并没有回答你所有的问题,但我已经让它工作了,所有其他的答案都遗漏了一件事——当你用“调整大小”事件重绘地图时,你将失去地图的中心位置。因此,如果您的地图以某个位置为中心,您还需要使用setCenter再次更新地图的中心。
Also, you don't want to initialize the map every time the tab change is triggered, as that is not efficient and can result in extra geocodes. First, you need to save your centered location, which can be a static lat/long, or if geocoding, may look something like this:
此外,您不希望每次触发选项卡更改时都初始化地图,因为这样做效率不高,并且会导致额外的地理编码。首先,您需要保存您的居中位置,它可以是静态纬度/经度,或者如果是地理编码,则可能如下所示:
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);
}
});
Then
然后
$("#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!
}
});
Where 'mapTab' is the ID of your mapTab, and 'map' is the var name for your map object.
其中 'mapTab' 是您的 mapTab 的 ID,而 'map' 是您的地图对象的 var 名称。
回答by Keyo
I load the maps after the tab has been shown.
我在显示选项卡后加载地图。
This is hacky but it worked for me. Simply store the url of the map iframe inside the iframes rel attribute like so:
这很hacky,但它对我有用。只需将地图 iframe 的 url 存储在 iframes rel 属性中,如下所示:
<iframe width="490" height="300" rel="http://maps.google.com/maps?f=q&source=s..."></iframe>
This event will set the iframe src attribute to the url inside the rel.
此事件会将 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);
}
});
回答by Vaughn
Be sure that the code that initializes your map is called BEFORE the snippet that initializes your tabs.
请确保在初始化您的选项卡的代码段之前调用初始化您的地图的代码。
The only annoyances I had were that a click on the map tab made the browser jump to focus on the map and that it broke out of the default border that jQuery puts around the main tabs container. I added a return false onclick call to the map tab's a tag to handle the first and a simple border-size: 0 on the main tabs div to handle the second.
我唯一的烦恼是单击地图选项卡会使浏览器跳转到地图上,并且它超出了 jQuery 在主选项卡容器周围放置的默认边框。我添加了一个 return false onclick 调用到地图选项卡的 a 标记来处理第一个和一个简单的 border-size: 0 在主选项卡 div 上处理第二个。
All of this worked for me.
所有这些都对我有用。
Good luck!
祝你好运!
回答by Andy
I had this problem too, I was loading the maps through AJAX.
我也有这个问题,我是通过 AJAX 加载地图的。
It seems the problem with percentage was to do with the panel not having any set size (the one containing the loaded markup).
百分比的问题似乎与没有任何设置大小的面板(包含加载的标记的面板)有关。
Using the following code when creating the tabs helped me a lot:
在创建选项卡时使用以下代码对我有很大帮助:
$("#mainTabs").tabs({'show': function(event, ui){
$(ui.panel).attr('style', 'width:100%;height:100%;');
return true;
}});
回答by Dave
I've been through every forum searching for the answer to this...they all said to use the
我已经通过每个论坛寻找这个问题的答案......他们都说要使用
map.checkResize()
map.checkResize()
solution....nothing seemed to work...then I...why not initialize the tab when the tab is shown so i used this
解决方案......似乎没有任何效果......然后我......为什么不在显示选项卡时初始化选项卡所以我使用了这个
$("#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" is the id of my tab that holds my google map v3.
“service5”是包含我的谷歌地图 v3 的标签的 ID。
Hope this works for you!
希望这对你有用!
回答by Andrés Sepúlveda
Hey guys, this code fixes the error but in IE not working. After searching and searching, I discovered that we must add the following line and everything works to perfection:
嘿伙计们,这段代码修复了错误,但在 IE 中不起作用。经过搜索和搜索,我发现我们必须添加以下行,一切都完美无缺:
< !--[if IE]>
< style type="text/css">
.ui-tabs .ui-tabs-hide { position: relative; }
< /style>
< ![endif]-->