同样在这里。我注意到的是,v3 在平移地图时会触发很多事件,并且浏览器往往会阻塞(尤其是 FF)。我这样说是因为我也使用了 Bing Maps API,并且每秒的事件数viewchange
(相当于center_changed
Google 中的)要小得多。它们还提供了addThrottledHandler()
减少生成事件数量的方法。
据我所知,谷歌地图似乎会在地图视图更新之前center_changed
为每个事件触发一个事件。mousemove
因此,您会生成很多事件,但它们都不会在屏幕上复制;浏览器在地图视图更新时阻塞,或者地图可能会等到没有更多更改时才会更新视图。
编辑:如果我们阻止某些mousemove
事件到达谷歌地图,那么浏览器将不会阻塞mousemove
事件以及谷歌地图从该事件生成的所有其他事件,例如center_changed
,地图将顺利平移。
为此,我们向#map
div 添加了一个事件侦听器(我们也可以将其添加到body
标签中)。我们为捕获阶段添加事件。当鼠标在屏幕上移动时,body
标签首先接收事件,然后是我们的#map
div,然后是 Google Maps 元素(div、tile)。这是捕获阶段。之后是冒泡阶段,事件从 Google 地图元素返回到我们的#map
div,然后返回到body
标签。通常事件处理程序是为冒泡阶段注册的,所以如果我们为捕获阶段注册一个处理程序,我们可以取消事件,因此该事件将没有冒泡阶段。这也意味着谷歌地图将不会收到该事件。
你可以增加period
和space
参数来杀死更多的事件。杀死太多事件意味着地图将开始从一个位置跳到下一个位置。杀死太少意味着所有事件都将到达谷歌地图,并且浏览器将阻塞谷歌地图新生成的事件,因此地图将从一个位置跳转到下一个位置。一些中间立场效果最好。
现在毕竟这些,谷歌地图不会像必应地图那样流畅。这是因为 Bing 地图使用惯性:当您猛烈移动地图时,地图将开始缓慢跟随鼠标,然后越来越快。这确实创造了一个非常光滑的平底锅。
我发现一个有趣的事实是,mousemove
即使鼠标不动,Google Chrome 和 Opera/Chrommium 也会每秒生成一个事件!此代码也将终止这些事件(因为distance
这些事件为零)。
http://jsfiddle.net/uNm57/ (检查 Firefox 中的 js 控制台;您应该会看到一些已停止的事件,然后是一个允许的事件)
<html>
<head>
<style type='text/css'>
#map {
position: absolute;
width: 100%;
height: 100%;
margin: 20px;
}
</style>
<script type='text/javascript'>
var last = {time : new Date(), // last time we let an event pass.
x : -100, // last x position af the event that passed.
y : -100}; // last y position af the event that passed.
var period = 100; // ms - don't let pass more than one event every 100ms.
var space = 2; // px - let event pass if distance between the last and
// current position is greater than 2 px.
function init_map() {
map_div = document.getElementById("map")
// map
var map_options = {
center: new google.maps.LatLng(45.836454, 23.372497),
zoom: 8
};
map = new google.maps.Map(document.getElementById("map"), map_options);
// register event handler that will throttle the events.
// "true" means we capture the event and so we get the event
// before Google Maps gets it. So if we cancel the event,
// Google Maps will never receive it.
map_div.addEventListener("mousemove", throttle_events, true);
};
function throttle_events(event) {
var now = new Date();
var distance = Math.sqrt(Math.pow(event.clientX - last.x, 2) + Math.pow(event.clientY - last.y, 2));
var time = now.getTime() - last.time.getTime();
if (distance * time < space * period) { //event arrived too soon or mouse moved too little or both
console.log("event stopped");
if (event.stopPropagation) { // W3C/addEventListener()
event.stopPropagation();
} else { // Older IE.
event.cancelBubble = true;
};
} else {
console.log("event allowed: " + now.getTime());
last.time = now;
last.x = event.clientX;
last.y = event.clientY;
};
};
</script>
</head>
<body onload = "init_map()">
<div id="map"></div>
</body>
</html>