Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***

Posted

技术标签:

【中文标题】Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***【英文标题】:Google Maps API v3 not loading without fitbounds, zooming causing infinite loop/*** 【发布时间】:2012-07-30 10:52:08 【问题描述】:

上一个问题: stack overflow with Google maps API (IE7 IE8) 同时我发现了以下问题:Google Maps API v3: Can I setZoom after fitBounds?

当我在地图上有多个标记时,那里的解决方案工作得很好。但是,当我访问 groupbke.young.netaffinity.net 的子页面时,例如。 https://groupbke.young.netaffinity.net/hotels/ireland/dublin/dublin/young-testing-hotel-liege/specials/bed-and-breakfast 只有当 map.fitBounds() 被调用时,地图才会加载。另一方面,即使地图没有加载,当我在地图画布上方滚动时,它也会抛出堆栈溢出错误。 如果我尝试使用 setZoom,无论如何都会引发堆栈溢出。

有什么想法吗?

var hoteldata = [
['Young Testing Hotel - Liège', 53.33932, -6.261427, '<div class="nearby-hotel"> <h1><a href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege">Young Testing Hotel - Liège</a></h1> <div class="star-rating-1"></div><div class="clear"></div> <div class="nearby-hotel-image l"> <a href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege"><img src="http://groupbke.young.netaffinity.net/bookings/images/imagecache/3/0C9DBC143E18ED64059C1696A52D2941-60x60.jpg" border="1" class="imagetype1"/></a> </a> </div> <div class="nearby-hotel-description l">  <a class="nearby-hotel-desc" href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege">Dublin\'s most luxurious design hotel is located in the heart of the city. Experience the best of both worlds when staying at this chic haven, to one side the tranquility and calm of St Stephen\'s Green and to the other, Grafton Street, Dublin\'s finest shopping avenue.    From its central location, in amongst this buzzing vibrant city it is an easy stroll to explore the leading cultural, historical and leisure attractions. Or just step out to the chic shopping, high energy bars, fine dining restaurants and chattering Cafes.</a> <a href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege" class="btn-small">Book Now</a> </div> <div class="clear"></div> </div>', 4]
];
function initialize(mapid) 
var myOptions = 
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    mapTypeControl: false
;
var bounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById(mapid), myOptions);
var infowindow = new google.maps.InfoWindow();
var markers = [];

for (i = 0; i < hoteldata.length; i++) 
    var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
    bounds.extend(latLng);
    var img = '/images/hotel-marker.png';
    if (hoteldata[i][4] == 2) 
        img = '/images/country-marker.png';
    
    if (hoteldata[i][4] == 3) 
        img = '/images/guesthouse-marker.png';
    
    if (hoteldata[i][4] == 4) 
        img = '/images/hotel-self-marker.png';
    
    var marker = new google.maps.Marker(
    position: latLng,
    icon: img,
    shadow: '/images/marker-shadow.png'
    );
    markers.push(marker);
    bindInfoWindow(marker, map, infowindow, hoteldata[i][3]);



var clusterStyles = [
  
    opt_textColor: 'white',
    url: '/images/m3-blue.png',
    height: 65,
    width: 64
  ,
 
    opt_textColor: 'white',
    url: '/images/m3-green.png',
    height: 65,
    width: 64
  ,
 
    opt_textColor: 'white',
    url: '/images/m3-orange.png',
    height: 65,
    width: 64 
  
];

var mcOptions = 
    styles: clusterStyles,
    maxZoom:14

;


if (markers.length>1)
    var markerCluster = new MarkerClusterer(map, markers, mcOptions);
    map.fitBounds(bounds);
    google.maps.event.addListenerOnce(map, 'zoom_changed', function() 
            var oldZoom = map.getZoom();
            map.setZoom(oldZoom + (-7)); //Or whatever
    );
 else if (markers.length == 1)
    markers[0].setMap(map);
    //google.maps.event.clearListeners(map, 'zoom_changed');
    //google.maps.event.addListenerOnce(map, 'zoom_changed', function() 
        //  var oldZoom = map.getZoom();
        //  map.setZoom(oldZoom + (-7)); //Or whatever
    //  setTimeout('roomSetter(globalmap,globalzoom)',300);
    //);
    //google.maps.event.trigger(map,'zoom_changed');
    //google.maps.event.clearListeners(map, 'zoom_changed');
    //map.fitBounds(bounds);
    //var oldZoom = map.getZoom();
    //map.setCenter(bounds.getCenter());
    //map.setZoom(oldZoom+(-7));
    //map.setZoom(3);
    //globalmap=map;
    //globalzoom=map.getZoom()+(-7);
    //setTimeout('zoomSetter(globalmap,globalzoom)',300);



var globalmap;
var globalzoom;

function zoomSetter(map, zoom)
//map.setZoom(zoom);


function bindInfoWindow(marker, map, infowindow, html)  
google.maps.event.addListener(marker, 'click', function()  
    infowindow.setContent(html); 
    infowindow.open(map, marker); 
    ); 
 

function initmaps() 
initialize('map_canvas');
initialize('map_thumb');


google.maps.event.addDomListener(window, 'load', initmaps);

我设置了 3 个测试页来演示问题:

http://groupbke.young.netaffinity.net/maptest1.html

这有 setZoom() 函数并引发 *** 错误,即使这应该是正确的

http://groupbke.young.netaffinity.net/maptest2.html

除了将标记添加到地图之外,这没有任何作用。在地图上滚动缩放仍然会引发堆栈错误。

http://groupbke.young.netaffinity.net/maptest3.html

这有 fitBound(),理论上不好,但有效。之后不能调整缩放级别,否则会引发 *** 错误。滚动缩放有效。

【问题讨论】:

您的链接存在重大问题(与地图无关,看起来无法加载大量外部文件,包括所需的 css):groupbke.young.netaffinity.net/hotels/ireland/dublin/dublin/… 您的证书无效(错误的站点)并且已过期(一年前过期),因此浏览器将无法通过 HTTPS 连接。 【参考方案1】:

当您只有一家酒店时,您创建一个只包含一个点的LatLngBounds 对象:

for (i = 0; i < hoteldata.length; i++) 
    var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
    bounds.extend(latLng);
...

但您随后会执行 map.fitBounds(bounds) — 这会尝试无限缩放。虽然 API 应该能够处理这个问题是有争议的,但同样有争议的是,它会尝试完全按照您告诉它的去做。 IE 的行为可能与 Firefox 和其他浏览器不同。

您在问题中引用的代码中注释掉了fitBounds(),该代码 出现在您的在线页面中。由于该行仅适用于涉及一个标记且 bounds 对象是单个点的情况,因此我将其替换为简单的 setZoom()

map.setZoom(16);

【讨论】:

抱歉,我一直在努力寻找解决方案,但有细微的变化和很多评论。实际上与 fitBounds() 一样,它在 IE 和 FF 上也能正常工作。问题是没有 fitBounds(),我什么也没有显示,它会导致循环和堆栈溢出,就像现在一样。放入 setZoom() 将触发加载溢出 很好。你能提供一个演示者的链接吗?它不必是您网站上的真实页面;它可能是一个临时页面。无论哪种方式,请确保 (a) 您不使用代码; (b) 问题中引用了足够的代码来创建同样会失败的独立演示器。 谢谢,请在问题末尾添加 3 个链接。我不会玩那些。【参考方案2】:

我在上一个问题的答案中缺少的是必须设置初始缩放级别和中心。

    var myOptions = 
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: false,
            zoom:22,
            center: new google.maps.LatLng(50.820645,-0.137376)
    ;

还必须在多标记缩放调整中将事件更改为“idle”。

if (markers.length>1)
    var markerCluster = new MarkerClusterer(map, markers, mcOptions);
    map.fitBounds(bounds);
    google.maps.event.addListenerOnce(map, 'idle', function() 
        var oldZoom = map.getZoom();
        map.setZoom(oldZoom + (-7)); //Or whatever
    );

在那之后就像一个魅力。

【讨论】:

以上是关于Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***

Google Maps v3 API密钥不适用于本地测试

Google Maps Javascript API V3中的旋转标记

带标签的 Google Maps API v3 标记

Google Maps API v3 中的 Javascript 错误 (RefererDeniedMapError)

Google Maps api v3 工具:视觉扭曲?