In Google Maps API,
when listening to click events from the Map object,
the event will not be fired when a Polygon, Circle, Rectangle is clicked.
How to bubble up the click event to the Map object?
const circle = new google.maps.Circle({
center,
radius,
map,
});
// This event will not fire when clicking the circle
map.addListener("click", (e) => {
console.log('map click');
})
Example: https://jsfiddle.net/rphsf32e/14/
Clicking on the map will add a marker. However, if the click is over the circle, the click event will not fire from the map. Only from the circle.
Simplest solution is to make the Circle (and Polygon/Rectangle) "unclickable", set the property: clickable: false in the constructor:
const circle = new google.maps.Circle({
center: myLatlng,
radius: 100000,
map,
clickable: false
})
proof of concept fiddle
code snippet:
function initMap() {
const myLatlng = { lat: -25.363, lng: 131.044 };
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 7,
center: myLatlng,
});
const circle = new google.maps.Circle({
center: myLatlng,
radius: 100000,
map,
clickable: false
})
circle.addListener("click", (e) => {
alert('inside circle');
console.log(e)
});
map.addListener("click", (e) => {
new google.maps.Marker({
position: e.latLng,
map,
title: `${ e.latLng.lat() }, ${ e.latLng.lng() }`,
});
})
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Click Events</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"
async
></script>
</body>
</html>
Related
This code loads lat/lng data from an array, and creates markers in a loop as the index advances. With each loop iteration, an event listener is created for each marker which should delete that marker on a click event using marker.setMap(null). The markers are placed properly in the map, but clicking on any of them deletes the final marker in the array, instead of the marker that was clicked on. I would expect such behavior if the event listener were placed after the loop, picking up only the last marker, but it is inside the loop. It seems straightforward, but I can't figure out what the problem is after trying many variations. Thanks for any help!
<!DOCTYPE html>
<html>
<head>
<title>deleteMarkerTest.html</title>
<style>
html, body {height: 100%; margin: 0; padding: 0;}
#map-canvas, #map_canvas {height: 100%;}
</style>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
var markersToSet = [
{lat: 33.037430,lng: -117.090111,title: "1765"},
{lat: 33.038330,lng: -117.090195,title: "1766"},
{lat: 33.038013,lng: -117.087593,title: "1767"},
{lat: 33.035110,lng: -117.088516,title: "1768"},
{lat: 33.034447,lng: -117.089729,title: "1769"}
];
function initialize() {
var mapCenter = new google.maps.LatLng(33.037380,-117.090431);
var mapOptions = {
zoom: 16,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.TRAFFIC
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
for (i = 0; i < markersToSet.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(markersToSet[i].lat, markersToSet[i].lng),
title: markersToSet[i].title,
map: map
});
google.maps.event.addListener(marker, 'click', function(event) {
marker.setMap(null);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas">
</div>
</body>
</html>
The marker variable is left pointing to the last marker (so it gets deleted). Simplest way to fix it is to use function closure to associate the marker with the click event:
<!DOCTYPE html>
<html>
<head>
<title>deleteMarkerTest.html</title>
<style>
html, body {height: 100%; margin: 0; padding: 0;}
#map-canvas, #map_canvas {height: 100%;}
</style>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
var markersToSet = [
{lat: 33.037430,lng: -117.090111,title: "1765"},
{lat: 33.038330,lng: -117.090195,title: "1766"},
{lat: 33.038013,lng: -117.087593,title: "1767"},
{lat: 33.035110,lng: -117.088516,title: "1768"},
{lat: 33.034447,lng: -117.089729,title: "1769"}
];
function initialize() {
var mapCenter = new google.maps.LatLng(33.037380,-117.090431);
var mapOptions = {
zoom: 16,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.TRAFFIC
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
for (i = 0; i < markersToSet.length; i++) {
createMarker(markersToSet[i].lat,markersToSet[i].lng,markersToSet.title);
}
}
function createMarker(lat, lng,title) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
title: title,
map: map
});
google.maps.event.addListener(marker, 'click', function(event) {
marker.setMap(null);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas">
</div>
</body>
</html>
working example
Hello and thanks in advance. The following modified sample google code creates markers upon left mouse clicks, and adds those markers to an array. That part works fine. I have tried to add a second event handler that deletes a marker if there is a right click on it. I've tried a lot of variations without success. It is my understanding that the use of marker.setMap(null) would set the associated array element to null, and remove the marker from the display. Thanks again!
<!DOCTYPE html>
<html>
<head>
<title>Marker Test</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas, #map_canvas {
height: 100%;
}
#map-canvas, #map_canvas {
height: 650px;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
var map;
var markers = [];
function initialize() {
var NY = new google.maps.LatLng(40.739112,-73.785848);
var mapOptions = {
zoom: 16,
center: NY,
mapTypeId: google.maps.MapTypeId.TERRAIN
}
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
addMarker(event.latLng);
});
google.maps.event.addListener(map, 'rightclick', function(event) {
marker.setMap(null);
});
}
function addMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
markers.push(marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
You want the 'rightclick' event listener on the marker, not the map. Put it in the addMarker function:
function addMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
google.maps.event.addListener(marker, 'rightclick', function(event) {
marker.setMap(null);
});
markers.push(marker);
}
Note: this will remove the marker from the map, but won't remove it from the markers array.
Remove the one on the map, delete these lines:
google.maps.event.addListener(map, 'rightclick', function(event) {
marker.setMap(null);
});
I am using Google Maps Javascript API ver3 to display the world locations. Below is the sample code I am using:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=true">
</script>
<script type="text/javascript">
function addMarkers(location,locationDetail,map){
var color = "#000000"
if(locationDetail[1]=="A"){
color = "#FF0000";
scl = 3;
}
else if(locationDetail[1]=="B"){
color = "#0000FF"
scl = 4;
}
else if(locationDetail[1]=="C"){
color = "#00FF00"
scl = 5;
}
var marker = new google.maps.Marker({
position: location,
title: locationDetail[0],
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: scl,
fillColor: color,
fillOpacity:1,
strokeWeight:1
}
});
// To add the marker to the map, call setMap();
marker.setMap(map);
}
function initialize() {
//Marking Latitude and Longitude
var myLatlng = [
new google.maps.LatLng(24.466667,54.366667),
new google.maps.LatLng(-34.4,-58.24),
new google.maps.LatLng(-33.8641,151.0823)
];
var myLatlngDet = [
["Abu Dhabi","A"],
["Buenos Aires","B"],
["HOMEBUSH","C"]
];
//Map Options to customize map
var mapOptions = {
zoom:2,
center: new google.maps.LatLng(40,0),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapMaker: true,
minZoom : 2,
scrollwheel: false,
mapTypeControl:true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM_CENTER
},
scaleControl:true,
scaleControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
streetViewControl:true,
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
},
overviewMapControl:false,
zoomControl:true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.LEFT_CENTER
},
panControl:true,
panControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
}
};
//Generating map in the div
var map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
for(i=0; i < myLatlng.length; i++){
addMarkers(myLatlng[i],myLatlngDet[i],map);
}
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="height: 100%; width: 80%;">
</div>
</body>
</html>
The Problem is - Sometimes the markers get displayed properly but sometimes I get a javascript error as follows:
'Unexpected Call to Method or Property access'
main.js
Can you help me identifying the cause of the problem.
I am using IE8.
Thanks in advance
My guess is that it's the body's onload that is not waiting until googlemap's script is loaded. In theory the body can be loaded faster than the googlemap script (relevant discussion). Try putting
window.onload=initialize;
at the bottom of your script instead of using the body's onload and see if this solves your problem. I have a hard time reproducing this.
Update
You should simply wait until googlemap has loaded which follows after the window load. Have a look at this question: How can I check whether Google Maps is fully loaded?
This is unnecessarily difficult, thanks to CSS's vertical-align: middle oddities. I understand (though counter-intuitive) that if you want to vertically center text next to an image, you must do this to the image and not the text...
It seems that this approach only works when the text is in a span container, the image is defined by an img tag, and they are both within a div container.
That being said, I have an infowindow in Google Maps that contains an address (text) to the left of a Google StreetView display (image?). However, instead of the img tag the street view object is in a span container.
Here is the relevant code:
<!DOCTYPE html>
<html>
<head>
<title>address and street-view inside an infowindow</title>
<style type = "text/css">
*
{
margin: 0px;
padding: 0px;
}
html, body
{
height: 100%;
}
#map_canvas
{
min-height: 100%;
}
/* inside infowindow */
#userAddress
{
float: left;
}
#street_canvas
{
float: right;
width: 100px;
height: 100px;
vertical-align: middle;
}
</style>
</head>
<body>
<!-- map here -->
<div id = "map_canvas"></div>
<!-- Google Maps API -->
<script type = "text/javascript" src = "http://maps.googleapis.com/maps/api/js?&sensor=true&v=3.9"></script>
<script type = "text/javascript">
var map;
initialize();
function initialize()
{
var mapOptions =
{
center: new google.maps.LatLng(37.09024, -95.712891), // coordinates for center of the United States
zoom: 4, // smaller number --> zoom out
mapTypeId: google.maps.MapTypeId.TERRAIN // ROADMAP, SATELLITE, TERRAIN, or HYBRID
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
} // end of initialize
var coordinates = new google.maps.LatLng(37.414341, -122.07692159999999);
var address = "1401 North Shoreline Boulevard Mountain View, CA 94043";
setMarker(coordinates, address);
function setMarker(userCoordinates, userAddress)
{
var panorama = null;
// user address map marker created here
var marker = new google.maps.Marker(
{
map: map, // from the global variable
position: userCoordinates
});
// infowindow created here
var windowInfo = "<div>" +
"<span id = 'userAddress'>" + userAddress + "</span>" +
"<span id = 'street_canvas'></span>" +
"</div>";
var infoWindow = new google.maps.InfoWindow(
{
content: windowInfo
});
function setStreetView(infoWindow, userCoordinates)
{
google.maps.event.addListener(infoWindow, "domready", function()
{
if(panorama !== null)
{
panorama.unbind("position");
panorama.setVisible(false);
}
// options for streetview inside map marker
var panoramaOptions =
{
position: userCoordinates,
pov:
{
heading: 45, // northwest in degrees
zoom: 1,
pitch: 1 // 0 degrees is level
},
// removing all map controls
addressControl: false,
clickToGo: false,
enableCloseButton: false,
imageDateControl: false,
linksControl: false,
panControl: false,
scrollwheel: false,
zoomControl: false,
disableDoubleClickZoom: true
};
// initializing streetview and settings to global variable
panorama = new google.maps.StreetViewPanorama(document.getElementById("street_canvas"), panoramaOptions);
panorama.bindTo("position", marker);
panorama.setVisible(true);
});
} // end of setStreetView
setStreetView(infoWindow, userCoordinates);
// event listener for infowindow of map marker, onclick
google.maps.event.addListener(marker, "click", function()
{
infoWindow.open(map, this);
map.panTo(this.position);
});
// event listener for closing infowindow of map marker
google.maps.event.addListener(infoWindow, "closeclick", function()
{
// disable streetview, with the global variable
panorama.unbind("position");
panorama.setVisible(false);
panorama = null;
});
} // end of setMarker
</script>
</body>
</html>
See this for a reference on putting a streetview display inside of an infowindow.
So, it was much much easier than I thought -- a line-height attribute must be set in the CSS for the text, equal to the height specified by the streetview div. And that's it, the text is then "vertically centered":
/* inside the infowindow */
#userAddress
{
float: left;
line-height: 100px;
}
#street_canvas
{
float: right;
width: 100px;
height: 100px;
}
There is no need for vertical-align: middle in this case.
I have a fullscreen google maps web page similar to this http://wadehammes.com/dewey-beach/, now how can I grey down the whole area (map) except for a rectangle div-container?
I want to create the cool effect of looking the map "through a window", where the "window" is a div-rectangle, and also be able to interact with the map only on the area inside the rectangle (div-container).
I imagine CSS should do that, am I wrong? Any idea how to do that?
I hope I expressed well myself
Thanks
The idea is that you will need two maps, because Google doesn't let you apply a style to "just a part" of the map. So you'll have two versions: black & white, and color map. Then with CSS you hack the position one inside the other, and with JS you add support for user dragging. If you need to add extra things such as markers, or click actions, just remember to bind those events to both created maps: map & other. Check the demo I've created.
I've created this little demo in 10 mins, just copy-paste and it will work. The code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map Loop</title>
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<style>
#map-container{
height:400px; /* map height */
position:relative;
width:500px; /* map width */
}
#map-canvas{
height:400px; /* map height */
position:absolute;top:0;left:0;
width:500px; /* map width */
}
.loop{
height:200px;
overflow:hidden;
position:absolute;top:100px;left:150px; /* offset in map view */
width:200px;
}
#map-canvas2{
height:400px; /* map height */
margin:-100px 0 0 -150px; /* opposite to top and left in .loop */
width:500px; /* map width */
}
</style>
</head>
<body>
<div id="map-container">
<div id="map-canvas"></div>
<div class="loop">
<div id="map-canvas2"></div>
</div>
</div>
<script type="text/javascript">
function initialize() {
// 2 = color
// 1 = b&w
var mapDiv = $('#map-canvas2')[0];
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
disableDefaultUI: true, /* we dont need UI in the loop */
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var other = $('#map-canvas')[0];
var map2 = new google.maps.Map(other, {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: [{
stylers: [{ saturation: -100 }]
}]
});
// flag to prevent buggy behavior
var BLACK_WHITE_MAP = false;
google.maps.event.addListener(map, 'mousedown', function() {
BLACK_WHITE_MAP = false;
});
google.maps.event.addListener(map2, 'mousedown', function() {
BLACK_WHITE_MAP = true;
});
google.maps.event.addListener(map, 'bounds_changed', function() {
!BLACK_WHITE_MAP && map2.setCenter(this.getCenter());
});
google.maps.event.addListener(map2, 'bounds_changed', function() {
BLACK_WHITE_MAP && map.setCenter(this.getCenter());
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</body>
</html>