javascript Google Maps JS v3:地图显示:无;地图初始化后导致地图损坏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5930425/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 18:50:09  来源:igfitidea点击:

Google Maps JS v3: Map display: none; after map initialization causing corrupted map

javascriptgoogle-maps

提问by BentFX

Thiscertainly touches on previous questions regarding map display during initialization. Yet the issue here is with map display being set to none after map should have already initialized. The last line of my widow.onload sets the map to display: none; The map initialization should have already completed by that time, but the fact remains, the final call is causing the problem.

当然涉及到之前关于初始化期间地图显示的问题。然而,这里的问题是在地图应该已经初始化之后将地图显示设置为无。我的widow.onload 的最后一行设置地图显示:none; 到那时地图初始化应该已经完成​​了,但事实仍然存在,最终调用导致了问题。

window.onload(); function...

window.onload(); 功能...

window.onload = function(){
  changeTheme(me); // do it now so current_theme is avaible to switchTabs();
    switchTabs("tab3"); // sets map div visible
  initMaps(); // map initialization. code included.
  loadFavoritePlaces(); // asynch $getJSON call, adds markers. No matter the condition of map, markers appear in their proper locations.
  closePopup("images");
  closePopup("location"); // sets maps.mini_map display: none; Problems if we loadUserTable() later. Otherwise OK. Odd!
  closePopup("tweet");
  centerDiv();
  document.title = '@'+me.screen_name+' - PithyTwits.com';
  users[me.id_str] = me;
  getPage(); // asynch $.getJSON loads tweets. Not an issue.

  // Append a scroll event handler to tweet_div
  $("#tweet_div").scroll(function() {
    var pos = $(this)[0].scrollHeight - $(this).scrollTop();
    if(pos != prev_scroll){ // hack to prevent scroll function from firing twice
      prev_scroll = pos;
      if (pos == $(this).outerHeight()) {
        $("#throbber").fadeIn();
        getPage();
      }
    }
  });

  loadUserTable(me.id_str);
  /* loadUserTable(); calls switchTabs("tab1"); which sets map div display: none;
  if I comment this out the map initialization completes properly, but my 'tab1'
  doesn't get populated properly. And page doesn't start on 'tab1', which is required. */

// end window.onload()
}

initMaps(); function...

initMaps(); 功能...

function initMaps() {

    // markers list
  maps.markers = new Object;

  // visibility status'
  maps.markerStatus = new Object;
  maps.markerStatus['query'] = true;
  maps.markerStatus['tweet'] = true;
  maps.markerStatus['favorite'] = true;

  // define marker images
  maps.reticleImage = new google.maps.MarkerImage('images/reticle.png',
    new google.maps.Size(63, 63),
    new google.maps.Point(0,0),
    ...
    Declarations removed to streamline post.
    ...
    new google.maps.Point(0,0),
    new google.maps.Point(1, 13));
  maps.markerShape = {
      type: "poly",
      coords: [9,22,16,11,16,5,11,1,6,1,2,5,2,11,9,22]
      }

  // setup map options
  var latlng = new google.maps.LatLng(39.520427, -94.770621);
  var latlng2 = new google.maps.LatLng(46.1912, -122.1944);
  var myOptions = {
    zoom: 3,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.HYBRID
  };
  var myOptions2 = {
    zoom: 13,
    center: latlng2,
    disableDefaultUI: true,
    draggable: false,
    keyboardShortcuts: false,
    mapTypeControl: false,
    scrollwheel: false,
    mapTypeId: google.maps.MapTypeId.HYBRID
  };

  // initialize maps
  maps.main_map = new google.maps.Map(document.getElementById("map_div"), myOptions);
  maps.mini_map = new google.maps.Map(document.getElementById("mini_map"), myOptions2);

  // default map center markers
    maps.mini_map_marker = new google.maps.Marker({
    position: latlng2,
    map: maps.mini_map,
    icon: maps.favoriteMarker, 
    shadow: maps.markerShadow,
  });
  maps.reticleMarker = new google.maps.Marker({
    position: latlng,
    map: maps.main_map,
    shape: reticleShape,
    icon: maps.reticleImage,
  });

  // event handlers
  google.maps.event.addListener(maps.main_map, 'zoom_changed', mapZoomed);
  google.maps.event.addListener(maps.main_map, 'bounds_changed',
      function(){maps.reticleMarker.setPosition(maps.main_map.getCenter());});

  //idle event listener provided by @Guan in the marked answer.
  google.maps.event.addListenerOnce(maps.main_map, 'idle', function() {
      var div = document.getElementById("tab3_content"); 
      div.style.display = "none"; 
      div.style.position = "relative"; 
      div.style.left = "0px"; 
  });

  // initialize controls
  var controls = document.getElementById("visibility_controls");
  maps.main_map.controls[google.maps.ControlPosition.TOP_CENTER].push(controls);
  controls.style.display = "inline";
  var controls = document.getElementById("control_controls");
  maps.main_map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(controls);
  controls.style.display = "inline";
  var controls = document.getElementById("query_controls");
  maps.main_map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(controls);
  controls.style.display = "inline";
}

If I call loadUserTable(); at the end of window.onload(); I get this... (munged)

如果我调用 loadUserTable(); 在 window.onload() 的末尾;我明白了……(蒙混过)

Maps not properly initialized

地图未正确初始化

If I don't call loadUserTable(); at the end of window.onload(); I get this... (correct)

如果我不调用 loadUserTable(); 在 window.onload() 的末尾;我明白了……(正确)

Maps properly initialized

地图正确初始化

Since the problem stems from the maps display being set to none after the maps should have initialized, it would lead one to believe that the map initialization is actually happening non-syncronously. So how do I know when it is finished, and it is safe to hide the maps div? And also there is the question of why the mini_map seems to be dependent on visibility of the main_map, rather than its own visibility? I get the same results in both Chrome and Firefox, on Linux.

由于问题源于地图显示在地图应该初始化后被设置为无,因此人们会认为地图初始化实际上是非同步发生的。那么我怎么知道它什么时候完成,隐藏地图 div 是安全的?还有一个问题是为什么 mini_map 似乎依赖于 main_map 的可见性,而不是它自己的可见性?我在 Linux 上的 Chrome 和 Firefox 中得到相同的结果。

Any help is help :)

任何帮助都是帮助:)

Skip

跳过

UPDATE: I changed the final call to setTimeout("loadUserTable();", 1000); and 1 second is enough of a pause to let things work, but isn't what I want! Since @Jobsz verifies this is known issue, I'm going to resort to off screen initialization, and move the map into position either when needed for display, or hide it and put it in position after a short timeout.

更新:我将最终调用更改为 setTimeout("loadUserTable();", 1000); 1 秒钟足以让事情正常进行,但这不是我想要的!由于@Jobsz 验证了这是已知问题,因此我将求助于屏幕外初始化,并在需要显示时将地图移动到位,或者在短暂超时后将其隐藏并放置到位。

SOLUTION:Provided by @Guan(Checked answer)

解决方案:由@ Guan提供(已检查答案)

I did not want the map visible during initialization. But wanted it initialized and ready when the user chose that tab.

我不希望在初始化期间地图可见。但是希望它在用户选择该选项卡时初始化并准备就绪。

The map div is initially set thus...

地图 div 最初是这样设置的......

id="tab3_content" style="display: block;position: absolute; left: -1000px;"

That makes it visible, but offscreen to the left.

这使它可见,但在屏幕外左侧。

And then set a listener for the idle event in the map initialization...

然后在地图初始化中为空闲事件设置一个监听器......

google.maps.event.addListenerOnce(maps.main_map, 'idle', function() {
  var div = document.getElementById("tab3_content"); 
  div.style.display = "none"; 
  div.style.position = "relative"; 
  div.style.left = "0px"; 
});

That event fires once when the map is idle(ready). It hides the div and moves it into position on screen.

当地图空闲(准备好)时,该事件会触发一次。它隐藏 div 并将其移动到屏幕上的位置。

The loadUserTable() function is called in the normal program flow, and life is good. :)

正常程序流程中调用loadUserTable()函数,生活好。:)

回答by Hailwood

Could you try calling

你可以试试打电话吗

//map hold's a reference to your current map
google.maps.event.trigger(map, 'resize');

After the map/div containing it becomes visible?

在包含它的地图/div 变得可见之后?

回答by Guan

google.maps.event.addListenerOnce(map, 'idle', function() {
    $('#addstop').css({
        display: 'none',
        left: '0',
        top: '0'
    });
});

This event happens only once after the map is fully loaded and 'idle'

此事件仅在地图完全加载且“空闲”后发生一次

回答by Atticus

Yup -- I had this same problem.

是的 - 我有同样的问题。

What I did was trigger the initialization after the event button that displays the hidden map is clicked.

我所做的是在显示隐藏地图的事件按钮被点击后触发初始化。

So I have a hidden div, when it's clicked to shown, i display it and then initalize it. Is this doable for what you're trying to achieve? I'm assuming you want performance in that you'd prefer the click to instantly show a populated map -- however it isn't too slow to populate the small area you're tying to if you do it on the click event.

所以我有一个隐藏的 div,当它被点击显示时,我显示它然后初始化它。这对于您想要实现的目标是否可行?我假设您想要性能,因为您希望点击立即显示一个已填充的地图——但是,如果您在点击事件上执行此操作,填充您要绑定的小区域并不会太慢。

回答by cameraphp

Just this may help you.

只是这可能对你有帮助。

I just have an application that uses tabs mixed with gmap divs.

我只有一个使用与 gmap div 混合的选项卡的应用程序。

I was fix same problems. Console just show corruption image message. Your ideas help a lot!

我正在解决同样的问题。控制台只显示损坏图像消息。你的想法很有帮助!

I just use this

我只是用这个

$("#tab-3").click(function(){

$(".tab-3").removeClass("ui-screen-hidden");

$(".tab-1").addClass("ui-screen-hidden");

$(".tab-2").addClass("ui-screen-hidden");

initializedonationlocation();


})

  function initializedonationlocationdr() {
  var directionsDisplay = new google.maps.DirectionsRenderer();
  geocoder2 = new google.maps.Geocoder();
    infowindow2 = new google.maps.InfoWindow();
    var myOptions = {
      zoom: 10,
      center: new google.maps.LatLng(38.7,-121.59),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };



    var map2 = new google.maps.Map(document.getElementById('my_map_donation_donationreceipt'),
        myOptions);

    google.maps.event.addListener(map2, 'click', function(e) {

     geocoder.geocode(
          {'latLng': e.latLng},
          function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[0]) {
                if (marker2) {
                  marker2.setPosition(e.latLng);
                } else {
                  marker2 = new google.maps.Marker({
                     position: e.latLng,
                     map: map2});
                }
                infowindow2.setContent(results[0].formatted_address);


                var postCode = extractFromAdress(results[0].address_components, "postal_code");
                var street = extractFromAdress(results[0].address_components, "route");
                var town = extractFromAdress(results[0].address_components, "locality");
                var country = extractFromAdress(results[0].address_components, "country");
                var state = extractFromAdress(results[0].address_components, "administrative_area_level_1");

                $("#city_donationdr").val(town);
                $("#state_donationdr").val(state);
                $("#zip_donationdr").val(postCode);
                $("#address_donationdr").val(street); 
                infowindow2.open(map2, marker2);

                // Changing window

                 var prevSelection3 = $("#tabmap").val();
                    var newSelection3 = $("#navbar2 ul li").children("a").attr("data-tab-class");
                    $("."+prevSelection3).addClass("ui-screen-hidden");
                    $("."+newSelection3).removeClass("ui-screen-hidden");
                    prevSelection3 = newSelection3;
                    $("#tabmap").val(prevSelection3);


                document.getElementById('geocoding').innerHTML = "";
                $("#coords_donationdr").val(e.latLng);
                $("#address_donationdr").focus();
                GetCurbSideCoordsDR(directionsDisplay,map2);
              } else {
                document.getElementById('geocoding').innerHTML =
                    'No results found';
              }
            } else {
              document.getElementById('geocoding').innerHTML =
                  'Geocoder failed due to: ' + status;
            }
          });

    });

  }

I only call initialization only when tab that contain gmap is showed. NOT before. Many forums show gmap initialization at pages loading. In conbination with tabs, just only call initialization after tab appears.

我只在显示包含 gmap 的选项卡时才调用初始化。不是之前。许多论坛在页面加载时显示 gmap 初始化。结合tabs,只在tab出现后调用初始化。