stopEventPropagation不适用于移动safari或chrome dev工具仿真

时间:2016-03-14 20:49:25

标签: google-maps google-maps-api-3 mobile-safari google-chrome-devtools

用例;点击标记打开infowindow,点击地图关闭它。

function stopEventPropagation(e) { var evt = e ? e : window.event; evt.cancelBubble = true; if (evt.stop) evt.stop(); if (evt.stopPropagation) evt.stopPropagation(); if (evt.stopImmediatePropagation) evt.stopImmediatePropagation(); if (evt.preventDefault) evt.preventDefault(); evt.returnValue = false; } function initialize() { var map = new google.maps.Map(document.getElementById('map-canvas')); var infowindow = new google.maps.InfoWindow(); var bounds = new google.maps.LatLngBounds(); var point = new google.maps.LatLng(49.277, -123.125); var RichMarkerDiv='<div style="width:100px; height:100px;border:solid black 1px;">RichMarker</div>'; var marker = new RichMarker({ position: point, map: map, title: 'RichMarker', content: RichMarkerDiv }); google.maps.event.addListener(marker, 'click', function(e) { stopEventPropagation(e); infowindow.setContent(this.title); infowindow.open(map, this); }); bounds.extend(point); google.maps.event.addListener(map, 'click', function(event) { infowindow.close(); }); map.fitBounds(bounds); } initialize(); 用于防止标记点击传播到地图(点击地图会关闭信息窗口),这在Chrome中运行良好,但在移动设备(iphone 5)或Chrome本身模拟同一部手机,事件没有停止(因此信息框未显示,或者中间关闭)。

<?php
function myException($exception) {
  echo "<b>Exception:</b> " . $exception->getMessage();
}

set_exception_handler('myException');

throw new Exception('Uncaught Exception occurred');
?> 

可在此处测试:http://jsfiddle.net/hy7rrm28/4/

使用的富标记库对于传递事件有一个很小的改进,如下所示:https://code.google.com/p/google-maps-utility-library-v3/issues/detail?id=280

注意:这项工作大约一周前,所以它可能与谷歌地图内的更新或这些浏览器(?)有关。

1 个答案:

答案 0 :(得分:1)

我最近解决了我创建的自定义Google地图标记的类似问题,我相信我知道发生了什么。我的代码与你的代码相似。

如果您不知道(我在遇到此问题之前没有),在移动设备上,当您点击屏幕时,会触发TouchEvent(https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent)...这个TouchEvent不会在桌面上创建。

在桌面上,我的代码有效,因为我认为标记和地图与同一事件进行交互是正确的:一个MouseEvent。

在移动设备上,当我将调试器放入此代码的回调中时 - google.maps.event.addListener(地图,&#39;点击&#39;,回调) - 我找到了&#39;窗口.event&#39;对象实际上是一个TouchEvent(当我在我的标记上检查click事件时,它正在与MouseEvent进行交互)。很明显,我需要阻止TouchEvent的发生。

当我听到&#39; touchend&#39;在我的标记上的事件和停止的传播,这停止了在移动设备上发生的任何点击事件(包括标记和地图上)。我把这个代码插入你的小提琴,因为类似的东西对我有用。不幸的是,它并没有在你的小提琴中起作用。

google.maps.event.addDomListener(marker, "touchend", function(e) {
  e.stopPropagation();
  infowindow.setContent(this.title);
  infowindow.open(map, this);
});

为什么它不起作用,我不能立即确定,但我的猜测是解决方案非常接近(可能问题与我的标记和RichMarker之间的差异有关? &#39; div&#39;我使用addDomListener on不是谷歌地图对象。也许这就是它?)。上面的解决方案(或类似的东西)的唯一问题是我希望在标记上发生其他事件(例如双击),我需要做一些不同的事情(因为停止传播&#39; touchend&#39;事件将阻止在对象上触发其他点击事件)。我最终创建了一个名为&#39; touchMobileEvent&#39;的变量。并将其设置为false。当&#39; touchend&#39;事件在标记上触发(仅在移动设备上触发),我将其设置为true,点击事件将在标记上触发,然后我在地图的点击事件回调中创建了一个条件,将touchMobileEvent设置为false而不是触发点击事件。当触发双击事件时,我也将其恢复为假:

创建变量以检查是否正在进行touchMobileEvent:

var touchMobileEvent = false;

在我的标记上设置事件:

google.maps.event.addDomListener(div, "touchend", function(e) {
  touchMobileEvent = true;
});

google.maps.event.addDomListener(div, "click", function(e) {
  e.stopPropagation();
  self.triggerClickEvent();
});

google.maps.event.addDomListener(div, "dblclick", function(event) {
  event.stopPropagation();
  event.preventDefault();
  self.triggerDblClickEvent();
  touchMobileEvent = false;
});

在我的地图上设置活动:

google.maps.event.addListener(map, 'click', function(e){
  if (touchMobileEvent) {
    touchMobileEvent = false;
  } else {
    mapClickEvent();
});

希望有所帮助。我建议检查每个回调中触发/捕获的各种事件。我最初的错误是假设事件监听器正在与同一事件进行交互(实际上我正在停止传播MouseEvent,但没有对在移动设备上创建的TouchEvent做任何事情)。