Google Maps API v3 + jQuery UI选项卡存在问题


70

使用Google Maps API在jQuery UI选项卡中呈现地图时,存在许多似乎是众所周知的问题。我已经看到有关类似问题的SO问题(例如,这里这里),但是那里的解决方案似乎仅适用于Maps API的v2。我检查过的其他参考资料在这里这里,以及我可以通过Googling挖掘的几乎所有内容。

我一直在尝试将地图(使用API​​的v3)填充到具有混合结果的jQuery标签中。我正在使用所有组件的最新版本(当前是jQuery 1.3.2,jQuery UI 1.7.2,不了解Maps)。

这是标记和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 Tabs文档(以及我链接的两个问题的答案)中所述的左偏技术根本不起作用。实际上,功能最佳的代码改用CSS .ui-tabs .ui-tabs-hide { display: none; }
  • 使地图完全显示在选项卡中的唯一方法是将CSS的width和height设置#map_canvas为绝对值。将宽度和高度更改为auto100%导致地图根本不显示,即使已经成功渲染(使用绝对宽度和高度)也是如此。
  • 我找不到它在Maps API之外的任何地方记录,但是map.checkResize()将无法再使用。相反,您必须通过调用触发一个调整大小事件google.maps.event.trigger(map, 'resize')
  • 如果未在绑定到tabsshow事件的函数内部初始化地图,则地图本身会正确呈现,但控件不会正确显示-大多数只是明显丢失。

所以,这是我的问题:

  • 还有其他人有完成相同壮举的经验吗?如果是这样,由于记录的技巧对Maps API v3不起作用,您如何确定实际可行的方法?
  • 如何根据jQuery UI文档使用Ajax加载选项卡内容?我还没有机会尝试使用它,但是我猜想它将进一步打破Maps。使它正常工作的机会是什么(或者不值得尝试)?
  • 如何使地图填充尽可能大的区域?我希望它能填充选项卡并适应页面大小调整,这与在maps.google.com上所做的方式大同小异。但是,就像我说的那样,我似乎只限于对地图div应用绝对宽度和高度CSS。

抱歉,如果您花了很长时间,但这可能是Maps API v3 + jQuery标签的唯一文档。干杯!


我发现google maps组对我做jquery + maps很有帮助。我没有使用选项卡或jquery ui。
杰伊(Jay)

据我所知,所有问题都是将地图放入jQuery UI选项卡的直接结果。尽管地图小组中的人可能对此有经验,但似乎不是这个问题的发源地。我可能最终会四处询问。
马特·鲍尔,

真可惜 他们在API部分方面非常有帮助,但在jquery方面无济于事。
杰伊(Jay)

Answers:


22

注意:此答案收到了无效的第三方编辑,实际上已替换了其内容,而第三方编辑则不应该这样做。但是,结果可能比原始结果有用,因此下面提供了这两个版本:


  • 经过Anon的一番编辑后,Ano于2010年创作了原始版本

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

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

Blech-谷歌不好,没有cookie。


  • 用户Eugeniusz Fizdejko的完整重写表格2012:

对我来说,添加标记时有效:

var marker = new google.maps.Marker({
    position: myLatlng,
    title:"Hello World!"
});

google.maps.event.addListener(map, "idle", function(){
    marker.setMap(map);
});

太棒了 我在jquery mobile / phonegap应用程序上遇到此问题,此修复程序为我解决了该问题!
Brade

1
这将我引到我的答案,上面指向code.google.com的链接已在几天前使用引导程序选项卡进行了更新,并且此Google地图发布了$('a [data-toggle =“ tab”]')。on('shown .bs.tab”,函数(e){google.maps.event.trigger(map,'resize'); map.setZoom(map.getZoom());})
NinjaKC 2015年

13

其实是我在上面的答案。jQueryUI网站提供了答案,这里是:

为什么...

...我的滑块,Google Map,sIFR等在置于隐藏(非活动)标签中时不起作用?

任何需要进行尺寸计算以进行初始化的组件都不会在隐藏的选项卡中工作,因为选项卡面板本身是通过显示隐藏的:无,因此内部的任何元素都不会报告其实际宽度和高度(在大多数浏览器中为0) 。

有一个简单的解决方法。使用左偏技术隐藏不活动的选项卡面板。例如,在样式表中,将类选择器“ .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()。


1
请修改您的旧答案。最重要的是,我解决了以下事实:jQueryUI网站建议的左偏技术在这种情况下不起作用。
马特·鲍尔

抱歉-我不知道可以编辑现有评论。我一直都在博客上,习惯是想“一旦我吐了,我就无法收回它”。我只能告诉您的是,此页面的选项卡中的地图/街道视图非常完美: jackying.brixwork.com/showlisting.php/63/…能做的最好的就是向您显示代码,也许您可​​以进行比较并查看缺少/不同的地方。.在我找到发布的解决方案之前,我的街景视图在过去的数天中都无法正常工作。
jeffkee 2010年

#example指的是什么?是地图还是标签的ID?resizeMap()是地图的V3函数吗?
bo-oz

12

只需为隐藏选项卡重新定义css类:

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

良好的修复,如果你不产生摹地图-只需要加一个上(“点击”)重置选项卡div的CSS ..
Q工作室

9

这是您可以对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
});

我不确定空闲事件应该如何有所帮助。即使触发了,如果在用户决定拖动然后变得空闲之前渲染仍然被弄乱了,那有什么好处呢?调整大小在选项卡显示事件的上下文中或在超时/间隔中很有用。
computrius 2014年

4

显示标签后,我会加载地图。

这很骇人,但对我有用。只需将地图iframe的网址存储在iframe的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);
            }
        });

好的,您是如何从iframe中获得经纬度坐标的?
托尼

4

这并不能回答您所有的问题,但是我已经解决了所有其他问题,而所有其他答案都缺少一件事-当您使用“调整大小”事件重绘地图时,您将失去地图所居中的位置。因此,如果地图以某个位置为中心,则还需要使用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名称。


1
通过将其绑定到选项卡click事件,这种触发地图调整大小的方法也适用于twitter引导选项卡:)您的解决方案是此处的最佳解决方案imo
haxxxton 2012年

2

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

我唯一的烦恼就是单击“地图”选项卡使浏览器跳转到地图上,使它脱离了jQuery围绕主选项卡容器放置的默认边框。我在地图标签的标签中添加了return false onclick调用,以处理第一个标签,并在主标签div中添加了一个简单的border-size:0以处理第二个标签。

所有这些都为我工作。

祝好运!


1

我曾经在每个论坛上都在寻找答案……他们都说要使用

map.checkResize()

解决方案...。似乎没有任何作用...然后我...为什么在显示标签时不初始化标签,所以我用了这个

$("#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”是保存我的Google Map v3的标签的ID。

希望这对您有用!


这为我工作,非常简单而优雅。我尝试了其他解决方案,但我想是因为我的设置与上面的示例不同,所以没有用(特别是resize方法调用)。但是确实如此,谢谢!
John Contarino 2015年

我发现使用激活而不显示可以更好地工作。我不知道为什么,但是show似乎冻结了我的标签,并且不允许它再次崩溃。
本杰明

1

大家好,这段代码解决了该错误,但在IE中无法正常工作。经过搜索之后,我发现我们必须添加以下行,并且所有内容都可以完美实现:

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

1

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

百分比问题似乎与面板没有任何设定尺寸(包含加载的标记的面板)有关。

创建标签时使用以下代码对我有很大帮助:

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

0

你可以打电话

map.fitBounds(bounds)

会刷新


1
fitBounds()的唯一问题是,如果您正在使用标记并且用户拖动了地图,则地图将迅速回到中心位置。
Mike Purcell

0

非常令人烦恼的问题,但是有一点可修改的地方,它是可修复的。关键是当您选择一个新的#tab时,使其相对位置的位置调整为每个tab的外部高度。这是我的做法:

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

0

通过异步加载API,然后从事件中关联到相关标签loadScript<a>标签中进行调用,就可以轻松实现此目的,onclick如下所示:

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

0

我遇到了同样的问题,没有答案对我有用。也许我不知道如何在代码中使用它们,所以我在选项卡菜单中添加了一个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>

0

Maps API v3(exp)和jQuery UI 1.10的另一种解决方案:

var pano = new google.maps.StreetViewPanorama(...);

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

0

我做了Keith所说的,它对我有用,在我的情况下,我使用jQuery航路点进行选项卡式导航,以便更好地理解这是我使用的代码:

在头

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

希望这对某人有帮助,谢谢大家!


0

我在中也遇到了同样的问题Semantic UIinit();当标签加载或您也可以绑定它时,在调用函数时该问题已解决。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.