在单击 Google Map API V3 时使用 infoWindow 或 InfoBox 触发事件
Posted
技术标签:
【中文标题】在单击 Google Map API V3 时使用 infoWindow 或 InfoBox 触发事件【英文标题】:Trigger event with infoWindow or InfoBox on click Google Map API V3 【发布时间】:2012-08-19 14:47:38 【问题描述】:我想知道当我使用 Google Maps API v3 单击 infoWindow 时如何触发事件。在此示例中,当我单击标记时,会显示一个信息窗口,其中包含一条独特的消息,具体取决于我单击的标记。我还希望能够单击信息窗口并显示一条警报,显示
“您点击了(__填写空白位置_)的信息窗口
我发现了一些使用 Google Maps API v2 和 jQuery 的示例,但并非仅使用普通的旧 Google Maps API v3。
<!doctype html>
<html lang="en">
<head>
<title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
<script type="text/javascript">
var cityList = [
['Chicago', 41.850033, -87.6500523, 1],
['Illinois', 40.797177,-89.406738, 2]
];
var demoCenter = new google.maps.LatLng(41,-87);
var map;
function initialize()
map = new google.maps.Map(document.getElementById('map_canvas'),
zoom: 7,
center: demoCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
);
addMarkers();
function addMarkers()
var marker, i;
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < cityList.length; i++)
marker = new google.maps.Marker(
position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
map: map,
title: cityList[i][0]
);
google.maps.event.addListener(marker, 'click', (function(marker, i)
var contentString = '<div id="infoWindow">'
+'<div id="bodyContent">'
+'<p>'
+ "This location is:<br>"
+ marker.title
+'</p>'
+'</div>'
+ '</div>';
return function()
infowindow.setContent(contentString);
infowindow.open(map, marker);
google.maps.event.addListener(infowindow, 'click', (function(i)
alert("You clicked on the infowindow for" + cityList[i][0]);
));
)(marker, i));
</script>
</head>
<body onload="initialize()">
<div id="basic-map" data-role="page">
<div data-role="header">
<h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
<a data-rel="back">Back</a>
</div>
<div data-role="content">
<div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
<div id="map_canvas" style="height:350px;"></div>
</div>
</div>
</div>
</body>
</html>
更新我最终也为 InfoBox 解决了这个问题,这包含在我的答案中。
【问题讨论】:
您可能有兴趣使用 snazzy-info-window 作为替代方案。 github.com/atmist/snazzy-info-window/blob/master/examples/… 【参考方案1】:好的,我为infoWindow
解决了这个问题,但后来我也为InfoBox
解决了这个问题,因为它更漂亮且更可定制。我是 JavaScript 新手,这些闭包可能非常棘手。
给infoWindow
<!doctype html>
<html lang="en">
<head>
<title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
<script type="text/javascript">
var cityList = [
['Chicago', 41.850033, -87.6500523, 1],
['Illinois', 40.797177,-89.406738, 2]
];
var demoCenter = new google.maps.LatLng(41,-87);
var map;
function initialize()
map = new google.maps.Map(document.getElementById('map_canvas'),
zoom: 7,
center: demoCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
);
addMarkers();
var boxText1 = document.createElement("div");
boxText1.id = "boxText1";
boxText1.className = "labelText1";
boxText1.innerHTML = "title1";//this is created earlier
var boxList = [];
function addMarkers()
var marker, i;
var infowindow = new google.maps.InfoWindow(
disableAutoPan: true
,isHidden:false
,pixelOffset: new google.maps.Size(-10, -10)
,closeBoxURL: ""
,pane: "mapPane"
,enableEventPropagation: true
);
for (var i = 0; i < cityList.length; i++)
marker = new google.maps.Marker(
position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
map: map,
id: i,
title: cityList[i][0]
);
var boxText = document.createElement("div");
boxText.id = i;
boxText.className = "labelText" + i;
boxText.innerHTML = cityList[i][0];
boxList.push(boxText);
google.maps.event.addListener(marker, 'click', (function(marker, i)
var contentString = '<div id="infoWindow">'
+'<div id="bodyContent">'
+'<p>'
+ "This location is:<br>"
+ marker.title
+'</p>'
+'</div>'
+ '</div>';
return function()
infowindow.setContent(boxList[this.id]);
infowindow.open(map, marker);
)(marker, i)); //end add marker listener
google.maps.event.addDomListener(boxList[i],'click',(function(marker, i)
return function()
alert('clicked ' + cityList[i][0])
)(marker, i));
//endfor
//end function
</script>
</head>
<body onload="initialize()">
<div id="basic-map" data-role="page">
<div data-role="header">
<h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
<a data-rel="back">Back</a>
</div>
<div data-role="content">
<div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
<div id="map_canvas" style="height:350px;"></div>
</div>
</div>
</div>
</body>
</html>
给InfoBox
<!doctype html>
<html lang="en">
<head>
<title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
<script type="text/javascript"
src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"> </script>
<script type="text/javascript"
src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js"> </script>
<script type="text/javascript">
var cityList = [
['Chicago', 41.850033, -87.6500523, 1],
['Illinois', 40.797177,-89.406738, 2]
];
var demoCenter = new google.maps.LatLng(41,-87);
var boxList =[];
function initialize()
map = new google.maps.Map(document.getElementById('map_canvas'),
zoom: 7,
center: demoCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
);
addMarkers();
function addMarkers()
for (var i = 0; i < cityList.length; i++)
marker = new google.maps.Marker(
position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
map: map,
id: i,
title: cityList[i][0]
);
var boxText = document.createElement("div");
boxText.id = i;
boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
boxText.innerHTML = "InfoBox for " + cityList[i][0];
var myOptions =
content: boxText
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-140, 0)
,zIndex: null
,boxStyle:
background: "url('tipbox.gif') no-repeat"
,opacity: 0.75
,width: "280px"
,closeBoxMargin: "10px 2px 2px 2px"
,closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif"
,infoBoxClearance: new google.maps.Size(1, 1)
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
;
var ib = new InfoBox(myOptions);
boxList.push(ib);
google.maps.event.addListener(marker,'click',(function(marker, i)
return function()
boxList[i].open(map, this);
)(marker, i));
google.maps.event.addDomListener(boxList[i].content_,'click',(function(marker, i)
return function()
alert('clicked ' + cityList[i][0])
)(marker, i));
//endfor
//end function
</script>
</head>
<body onload="initialize()">
<div id="basic-map" data-role="page">
<div data-role="header">
<h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
<a data-rel="back">Back</a>
</div>
<div data-role="content">
<div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
<div id="map_canvas" style="height:350px;"></div>
</div>
</div>
</div>
</body>
</html>
【讨论】:
如果我在信息框上执行点击功能,它会在标记中调用点击功能。你能帮忙解决这个问题吗?请在标记单击中添加警报以调试问题。 我写的代码是这样工作的:单击一个标记会打开信息框,然后,一旦信息框打开,如果单击它就会收到警报。您是否尝试做一些与此不同的事情? 我正在做你提到的同样的事情,但是你的代码在你提到的 android 中运行良好。但我只在 ios 中遇到问题。在 iOS 中,第二次点击 Infobox 只会打开警报,因为第一次点击会触发标记点击。 嗨,我正在尝试让您的示例在 plunker 中工作,但它不起作用。你知道为什么吗? plnkr.co/edit/cRdiu6QkZsnDoZBRM1sJ?p=preview【参考方案2】:InfoWindow 对象没有“点击”事件,所以你不能这样做
google.maps.event.addListener(infowindow, 'click',....
相反,您可以将事件处理程序附加到 DOM 对象,例如
function addMarker(latLng, name)
var marker = new google.maps.Marker(
map:map,
position:latLng
);
G.event.addListener(marker,'click',function(mev)
var div = document.createElement('div');
div.innerHTML = name;
div.onclick = function()iwClick(name);
infoWindow.setContent(div);
infoWindow.setPosition(mev.latLng);
infoWindow.open(map);
);
function iwClick(str)
alert(str);
;
你用它来称呼它
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
addMarker(chicago,'chicago');
【讨论】:
G 代表什么?【参考方案3】:谢谢!艾琳就是那个男人!你解决了我的问题!我已经打了4天了!如果您不熟悉闭包,* 会很痛苦。
这是我的工作代码(Sencha Touch 2 和 Google maps API v3)。它只允许打开一个信息窗口。
var openedInfoWindow = null;
var boxList = [];
var marker, i;
//build info box object
var infoWindow = new google.maps.InfoWindow(
enableEventPropagation: true,
);
//handle close
google.maps.event.addListener(infoWindow, 'closeclick', function()
openedInfoWindow = null;
);
//loop trough store data...
for(i in data)
//data
var itemData = data[i].getData();
//marker
var geopos = new google.maps.LatLng(itemData['lat'], itemData['lng']);
var marker = new google.maps.Marker(
position: geopos,
//icon: image,
map: map,
title: itemData['title'],
id: i,
animation: google.maps.Animation.DROP
);
//add info window content to DOM
var boxText = document.createElement("div");
boxText.id = i;
boxText.className = "labelText" + i;
boxText.data = itemData;
boxText.innerHTML = '<b>' + itemData['title'] + '</b>' + (itemData['distance'] ? ' (' + itemData['distance'] + ')' : '') + '<br />' + (itemData['address'] != itemData['title'] ? itemData['address'] : '') + (itemData['price'] ? '<br />' + itemData['price'] : '') + '<br /><a class="button">Meer info</a>';
boxList.push(boxText);
//add marker click event
google.maps.event.addListener(marker, 'click', (function(marker, i)
if (openedInfoWindow != null)
openedInfoWindow.close();
return function()
infoWindow.setContent(boxList[this.id]);
infoWindow.open(map, marker);
openedInfoWindow = infoWindow;
)(marker, i));
//when infowindow is clicked, open view...
google.maps.event.addDomListener(boxList[i],'click',(function(marker, i)
return function()
iStuddy.app.pushView('kames_detail',boxList[i].data);
)(marker, i));
【讨论】:
我在 infoWindow object specification(版本 3.24)上找不到任何关于enableEventPropagation
的文档【参考方案4】:
我的解决方案: 尝试在 xml 中使用 onClick
<InfoWindow onCloseClick=props.onToggleOpen>
<div onClick=()=>alert('hello') class="wow slideInLeft">
<img src="https://i.imgur.com/7IgBxnH.jpg" />
<div>nhà trọ cho thuê</div>
<div>1.500.000đ</div>
</div>
</InfoWindow>
【讨论】:
【参考方案5】:谢谢你们所有的cmets。我设法(在阅读了您的建议后)构建了一个无需修改 Infowindow 代码即可工作的示例。
infoWindow 本身应该只包含一个具有唯一 id 的占位符 div:
<InfoWindow
marker=this.state.activeMarker
visible=this.state.showingInfoWindow
onOpen=e =>
this.onInfoWindowOpen(this.props, e);
>
<div id="xyz" />
</InfoWindow>
在 Mapcontainer 中,您定义了一个 onInfoWindowOpen 回调,它使用 onClick 事件插入单个组件/容器并将其渲染到占位符 div:
onInfoWindowOpen = () =>
const button = (<button
onClick=
() =>
this.viewClinic(this.state.selectedPlace.slug)
>
View Details
</button>);
ReactDOM.render(React.Children.only(button),document.getElementById("xyz"));
这是一个工作示例:
https://codesandbox.io/s/k0xrxok983
一个更完整的例子MAP、Marker和InfoWindow:
https://codesandbox.io/s/24m1yrr4mj
【讨论】:
【参考方案6】:为了使信息窗口可点击,或者您希望在点击信息窗口内的任何标签时触发功能,dom 必须准备好。所以当 dom 准备好时,你可以调用一个函数。
google.maps.event.addListener(infowindow, 'domready', function()
document.getElementById('yourId').addEventListener("click", yourFucntionToCall);
function yourFucntionToCall()
Your fucntion code......
);
【讨论】:
以上是关于在单击 Google Map API V3 时使用 infoWindow 或 InfoBox 触发事件的主要内容,如果未能解决你的问题,请参考以下文章
Google Map API V3:如何将自定义数据添加到标记
Google Maps API v3 - 单击标记时如何“提醒”标记ID [重复]
使用 google map javascript api v3 在 google map 上添加多个目的地