web-dev-qa-db-ja.com

Google Maps API v3 + jQuery UIタブの問題

Google Maps APIを使用してjQuery UIタブ内で地図をレンダリングする場合、かなりよく知られていると思われる多くの問題があります。私はSO同様の問題について投稿された質問( here および here など)を見たことがありますが、そこの解決策はMaps APIのv2:チェックアウトした他の参照は herehere であり、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タブのドキュメント(およびリンクした2つの質問への回答)で説明されているオフレフトの手法を使用しても、まったく機能しません。実際、最高の機能を発揮するコードは、代わりにCSS _.ui-tabs .ui-tabs-hide { display: none; }_を使用します。
  • マップをタブに表示する唯一の方法は、CSSの_#map_canvas_の幅と高さを絶対値に設定することです。幅と高さをautoまたは_100%_に変更すると、既に完全にレンダリングされていても(絶対的な幅と高さを使用して)マップはまったく表示されません。
  • Maps API以外の場所にドキュメント化されたドキュメントは見つかりませんでしたが、map.checkResize()は機能しなくなりました。代わりに、google.maps.event.trigger(map, 'resize')を呼び出してサイズ変更イベントを発生させる必要があります。
  • マップがtabsshowイベントにバインドされた関数内で初期化されていない場合、マップ自体は正しくレンダリングされますが、コントロールはそうではありません-ほとんどは単に欠落しています。

だから、ここに私の質問があります:

  • この同じ偉業を成し遂げた経験がある人はいますか?その場合、文書化されたトリックがMaps API v3で機能しないため、実際に機能するものをどのように把握しましたか?
  • jQuery UI docs に従ってAjaxを使用してタブコンテンツをロードするのはどうですか?私はそれをいじる機会がありませんでしたが、私の推測では、Mapsをさらに壊すでしょう。動作する可能性は何ですか(または試してみる価値はありません)?
  • マップを可能な限り最大の領域に埋めるにはどうすればよいですか? maps.google.comで行われているのと同じように、タブを埋めてページのサイズ変更に適応させたいと思います。しかし、私が言ったように、絶対的な幅と高さのCSSのみをマップdivに適用することに固執しているようです。

時間がかかりすぎて申し訳ありませんが、これがMaps API v3 + jQueryタブの唯一のドキュメントである可能性があります。乾杯!

70
Matt Ball

注:この回答には、サードパーティの編集者が行うべきではない、コンテンツを本質的に置き換える無効なサードパーティの編集が含まれています。ただし、結果は元のものよりも有用である可能性があるため、両方のバージョンを以下に示します。


  • Anonによる1回の編集後の2010年のオリジナル著者Anonのバージョン

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

http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448 は、v2のcheckResize()のv3代替として提案されています。

Blech-悪いグーグル、クッキーなし。


  • ユーザーEugeniusz Fizdejkoの完全な書き換えフォーム2012:

私にとっては、マーカーを追加するときに動作します:

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

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

上記の私の答えを実際にスクラッチします。 jQueryUI Webサイトには答えがあり、ここにそれがあります:

なぜ...

...私のスライダー、Googleマップ、sIFRなどは、非表示(非アクティブ)タブに配置すると機能しませんか?

初期化に何らかの次元計算を必要とするコンポーネントは、タブパネル自体が表示によって非表示になっているため、非表示のタブでは機能しません。 。

簡単な回避策があります。非アクティブなタブパネルを非表示にするには、左上のテクニックを使用します。例えば。スタイルシートで、クラスセレクター「.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マップのcheckResize()を呼び出します。

13
jeffkee

非表示タブのcssクラスを再定義するだけです。

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

これは、Googleマップ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
});
9
jayarjo

タブが表示された後、マップをロードします。

これはハッキーですが、私にとってはうまくいきました。次のように、iframes rel属性内にマップiframeのURLを保存するだけです。

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

これですべての質問に答えられるわけではありませんが、機能するようになり、他のすべての答えに1つ欠けています。「サイズ変更」イベントでマップを再描画すると、マップの中心にあった場所が失われます。したがって、マップが位置の中心にある場合は、マップの中心を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名です。

4
paul

マップを初期化するコードは、タブを初期化するスニペットの前に必ず呼び出してください。

私が唯一悩まされたのは、マップタブをクリックするとブラウザがジャンプしてマップにフォーカスし、jQueryがメインタブコンテナの周囲に配置するデフォルトの境界線から外れたことです。マップタブのaタグにreturn false onclick呼び出しを追加して、最初のタグを処理し、メインタブのdivに0を追加して2番目のタグを処理します。

これはすべて私のために働いた。

幸運を!

2
Vaughn

私はすべてのフォーラムでこれに対する答えを探してきました...彼らは皆、

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マップv3を保持するタブのIDです。

これがあなたのために働くことを望みます!

1
Dave

私もこの問題を抱えていました。AJAXを介してマップをロードしていました。

パーセンテージの問題は、設定されたサイズ(ロードされたマークアップを含むパネル)がないパネルに関係していたようです。

タブを作成するときに次のコードを使用すると、非常に役立ちました

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

みんな、このコードはエラーを修正しますが、IEは機能しません。検索と検索の後、次の行を追加する必要があることを発見しました。

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

APIを非同期にロードする でこれを簡単に動作させ、次にloadScriptイベントの関連タブに関連付けられた<a>タグからonclickを呼び出すだけでそう:

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

あなたは電話することができます

map.fitBounds(bounds)

それはリフレッシュを行います

0
Juan arce

非常にいらいらする問題ですが、多少のハックアラウンドにより修正可能です。重要なのは、新しいタブを選択するときに、#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}
0
Tom Gordon

私は_Semantic UI_で同じ問題に直面していました。タブがロードされるとき、または同様にバインドできるときにinit();関数を呼び出している間に問題は修正されました。

0
Moxet Khan

キースの言うことをやったのですが、私にとってはうまくいきました。私の場合は、タブナビゲーションに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
yehanny

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
Wernight

私は同じ問題を抱えていて、答えはどれもうまくいきませんでした。コードでそれらを使用する方法を知らなかったので、Googleマップを初期化するためにタブメニューにonclickイベントを追加しました。しかし、それが良い習慣であるかどうかはわかりません。

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
arjang27