自定义缩放控制导致最大调用堆栈大小超出错误

Custom Zoom Control Results In Maximum Call Stack Size Exceeded Error

本文关键字:堆栈 出错 错误 调用 自定义 控制 缩放      更新时间:2023-09-26

我试图在iOS上使用谷歌地图JavaScript API时改变缩放增量。例如,不是从缩放14到缩放15,我想让它直接到缩放16,然后缩放18,等等……当用户使用缩放手势时。

我知道我可以通过按钮实现这一点,但我似乎找不到缩放手势的解决方案。我意识到需要跟踪zoom_changed事件。

在第17行和第19行分别添加map.setZoom(zoom + 2);map.setZoom(zoom - 2);时,我得到Maximum call stack size exceeded的错误。

查看这个JSFiddle: http://jsfiddle.net/2zmn9173/4/。这是我需要帮助的部分:

if (useragent.indexOf('iPhone') != -1) {
    google.maps.event.addListener(map, 'zoom_changed', function () {
        if (map.getZoom() > zoom) {
            alert("ZOOMED IN from Level " + zoom);
        } else if (map.getZoom() < zoom) {
            alert("ZOOMED OUT from Level " + zoom);
        }
        zoom = map.getZoom();
    });
}

上面的按钮演示了我想要实现的功能,但是使用了缩放手势

简单方法:

只在当前缩放不是偶数时设置新的缩放(这应该会停止无限循环)

    google.maps.event.addListener(map,'zoom_changed',function(){
      var z=this.getZoom();
      if(z%2){//when zoom is a odd number
        var fx=((!isNaN(this.get('z'))&&this.get('z')<z))?2:0;
        this.setZoom(Math.floor(z/2)*2+fx);
      }else{
        this.set('z',z);
      }
    });

演示:

function initialize() {
  var ctrl = document.getElementById('zoom');
  map = new google.maps.Map(document.getElementById('map_canvas'), {
      zoom: 14,
      center: new google.maps.LatLng(52.549,
        13.425),
      noClear: true
    }),
    map.controls[google.maps.ControlPosition.TOP_CENTER].push(ctrl);
  google.maps.event.addListener(map, 'zoom_changed', function() {
    var z = this.getZoom();
    if (z % 2) { //when zoom is a odd number
      var fx = ((!isNaN(this.get('z')) && this.get('z') < z)) ? 2 : 0;
      this.setZoom(Math.floor(z / 2) * 2 + fx);
    } else {
      this.set('z', z);
    }
    ctrl.innerHTML = this.getZoom();
  });
  google.maps.event.trigger(map, 'zoom_changed');
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
  height: 100%;
  margin: 0;
  padding: 0
}
#zoom {
  font: bold 2em Monospace;
  background: tomato;
  width: 30px;
  text-align: center;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_canvas">
  <div id="zoom"></div>
</div>

如果你在你的问题中添加这些行,你将在事件zoom_changed中触发事件zoom_changed,这将创建一个stackoverflow,因为它永远不会结束触发事件。

if (useragent.indexOf('iPhone') != -1) {
    google.maps.event.addListener(map, 'zoom_changed', function () {
        if (map.getZoom() > zoom) {
            map.setZoom(zoom + 2); //This will trigger "zoom_changed" again
        } else if (map.getZoom() < zoom) {
            map.setZoom(zoom - 2); //This will trigger "zoom_changed" again
        }
        zoom = map.getZoom();
    });
}

zoom = map.getZoom();之后将改变缩放,但其他事件将已经执行,我的建议是设置一个值,然后调用setZoom:

if (useragent.indexOf('iPhone') != -1) {
    google.maps.event.addListener(map, 'zoom_changed', function () {
        var newZoom = map.getZoom(), oldZoom = zoom;
        if (newZoom > oldZoom) {
            oldZoom + 2;
        } else if (newZoom < oldZoom) {
            oldZoom - 2;
        }
        zoom = oldZoom;
        map.setZoom(oldZoom);
    });
}