Just as the Title implies, I just added a "center_changed" listener to my map and the function is running more than once. I'm assuming it's because the center of the map is changing a bunch of times before the map comes to a rest, but I thought that that's what "drag" was for and that "center_changed only fires once after it comes to a rest??? The only reason I know its firing a bunch of times is because I have a drop shadow on the icon and it gets darker and darker over about two seconds before its completely black. If anyone needs my code, its below.
google.maps.event.addListener(map, 'center_changed', function() {
var zoomLevel = map.getZoom();
if (zoomLevel > 7) {
clearAll();
addmarker1();
addmarker2();
addmarker3();
addmarker4();
}
else {
clearAll();
}
});
These two functions fire only after your map comes to a rest
If you want your function to execute only when user drags(not programmatically) then use...
google.maps.event.addListener(map, 'dragend', function(){...}
But if you want your function to execute even when dragged, zoom changed programmatically(e.g. setZoom , fitBounds), then use...
google.maps.event.addListener(map, 'idle', function(){...}
Related
I'm developing an app with Google Maps and Angularjs. I have this code to control whether the zoom is changed
google.maps.event.addListener(map, 'zoom_changed', function(){
});
The question is, I need to execute this event only when the user changes the zoom. I have in my code a fitBounds() that change the zoom as well.
var latlngbounds = new google.maps.LatLngBounds();
for (var i = 0; i < latlng.length; i++) {
latlngbounds.extend(latlng[i]);
}
map.fitBounds(latlngbounds);
Is there an option to distinguish between user action and not?
The current accepted solution may not properly solve this question in a general case. Go to the interactive demo for map UI events in the Google Maps API docs. Note that if you position your cursor on the map and scroll with your mouse's scroll wheel, none of the mouse or drag events are fired because the mouse remains stationary.
The current solution assumes that no programmatic map updates will occur after the mouseover event, which may be true for the original poster's application but might not be true in a more general application.
I propose the alternate solution below.
First, wherever you programmatically update the map in your code, set a custom property on the map—we'll call ours systemZoomChange—that indicates the change was initiated programmatically.
var latlngbounds = new google.maps.LatLngBounds();
for (var i = 0; i < latlng.length; i++) {
latlngbounds.extend(latlng[i]);
}
map.systemZoomChange = true
map.fitBounds(latlngbounds);
Then on any event listeners, add a check for the custom systemZoomChange property, and reset it if flagged, to avoid acting on system events.
map.addListener('zoom_changed', function () {
if (map.systemZoomChange) {
map.systemZoomChange = false // Reset the flag for a system-initiated event
} else {
// Handle the user-initiated event
}
});
Ok, I found the way
google.maps.event.addListenerOnce(map, 'mousemove', function(){
google.maps.event.addListener(map, 'zoom_changed', function(){
});
});
First, it detects if the mouse moves and then if the zoom if changed and works properly!
On this website:
http://www.crunchpanorama.com/
you use the google maps zoom control slider to zoom and recluster markers. I want to capture this event as well and perform actions accordingly.
Problem is when reading google docs, all I could find is the zoom_changed event of map. However, this event is not only called when changing zoom using slider, but also when clicking marker (which zooms into marker). So zoom_changed will not help me:
google.maps.event.addListener(map, 'zoom_changed', function () {
...
I want to be able to target the zoom change on the control slider specifically. How can I go about this?
Maybe there's a workaround similar to this:
var self = this;
google.maps.event.addListener(marker, 'click', function() {
// Set a boolean variable to true to indicate a marker/cluster has been clicked
self._markerClicked = true;
});
google.maps.event.addListener(map, 'zoom_changed', function() {
// Check the boolean variable and run your code if it's false
if ( !self._markerClicked ) {
// Take action here
} else {
// Reset variable back to false
self._markerClicked = false;
}
});
Ran into this recently. This is the best solution I have found if you want to capture when the map default zoom buttons are clicked. This assumes that the zoom buttons are the only ones in the div map container.
$("#id-container-name").on("click", "button", whateverfunction());
I have a google map using V3 of the API. It has one marker on it which is draggable and then a load of other markers that are static. I have set up a dragend listener for the draggable marker which calls a function called clear_markers() like so:
google.maps.event.addListener(marker_0, "dragend", function() {
clear_markers();
});
function clear_markers()
{
if (markers) {
for (var i = 1; i <= markers.length; i++ ) {
if(typeof markers[i] !== "undefined") {
markers[i].setMap(null);
}
}
}
}
The reason I start the for loop at 1 and not 0 is that my draggable marker is the first marker so I want to clear all markers from the map except this one.
Here is the problem:
If I call clear_markers(); in any other way it works fine and the markers are removed from the map, so something like this works:
$('#mybutton').click(function() {
clear_markers();
});
When you drag and drop the green marker though and it's called from the dragend listener it does not work. The markers do get removed but then they immediately get re added again. I know they do get removed because if I put something in the clear_markers() function just after the for loop that kills the script, the markers get removed. But if the script is allowed to continue they are still there meaning they have been removed and then instantly added back on again.
I'm not calling any other code so it seems like a bug with the api to me. Does anyone have any ideas?
Here is a working example showing the problem:
https://tinker.io/64b68/1
Remove the markerClusterer. It is adding the markers back in and you aren't using it.
Update:
Since you need to keep it, if you want the markers to not be displayed, you need to remove them from the markerClusterer:
markerCluster.clearMarkers();
(but you will need to make it global to use it that way)
Your calling the eventListener the right way, just not in the right place in your code. I added a couple of alerts in your eventListener to see what was going on and if you see on the second alert, the markers are actually cleared - but once the alert box is closed the markers reappear. Try it yourself:
google.maps.event.addListener(marker_0, "dragend", function() {
alert("before calling clear_markers()");
clear_markers();
alert("markers should be cleared");
});
This means that once javascript runs into your "dragend" event listener, it will execute the code inside - but then it will go through the rest of the code as well and hence the markers get populated on the map again. You can fix this issue by adding your event listener to the end of your initialize() function after var markerCluster = new MarkerClusterer(map, markers, clusterOptions);.
text in italics is the wrong explanation, refer to the response below for the correct solution
/---------------------------------------------------------------------------------------------/
Disregarding my previous answer, allow me to re-edit. Again, you are calling the eventListener the right way. You will just need to add the following piece of code in the listener function to make sure the markers do not show up.
google.maps.event.addListener(marker_0, "dragend", function() {
clear_markers();
markerCluster.setMap(null);
});
It seems initiating the markerCluster overrides your clear function on the markers. So you will also need to clear the markerCluster from your map as well. Apologies for misguiding you in my previous response, markerCluster is a new concept to me as well.
I have a map, with a side bar div next to it. I'm trying to make it so that each marker on the map has a corresponding hyperlink in the sidebar, and when clicked, the info box for that marker pops up.
function linkClick(){
google.maps.event.trigger(gmarkers[cpid], "click");
}
content += ''+tmpName+"<br>";
$("#cplist").html(content);
cpid is a unique id for every point on the map, a value which is stored in the database with the rest of the information for the markers.
I have my markers on the map, and my links in the side bar, but I'm not sure how to make the connection between to two. I've created the 'linkClick' function to try and achieve this, but I just get the error:
ReferenceError: Can't find variable: linkClick
Currently all of the above code is in the loop which plots the markers on the map. I think i've included enough detail/code.
This is an example of what I want to achieve http://www.geocodezip.com/v3_MW_example_categories.html
I suggest changing your approach - rather than trying to push the click event, just go directly to the InfoWindow and call open. Somewhere else in your code you have a click event listener for each marker that opens an InfoWindow; so maintain reference(s) to your InfoWindow instances and open them, just the same as in the marker click event handler, when the onlick function attached to the link is called.
Or, if you are following a common strategy and working with a single, global InfoWindow, just write a function that accepts the cpid, places the necessary content in the InfoWindow, sets the correct position, and then calls InfoWindow.open( map ).
So if this is your event listener code:
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(tmpName+" is "+tmpDist+"km away from you.");
infowindow.open(map, this);
});
Add a new function:
function openInfoWindow( cpidAndWhateverElseParam ) {
infowindow.setContent(tmpName+" is "+tmpDist+"km away from you.");
infowindow.open(map, this);
}
And change your link code to be:
content += '<a href="javascript:openInfoWindow(' + cpidAndWhateverElseParam +
')">'+tmpName+"</a><br>";
For function you are not passing any variable,
thats why it is giving ReferenceError: Can't find variable: linkClick
function linkClick(cpid){
google.maps.event.trigger(gmarkers[cpid], "click");
}
content += <a onClick=linkClick(' + cpid + ')">'+tmpName+"</a><br>";
$("#cplist").html(content);
I made something similar once, but instead of use an element a i used a button and like javascript pure in the event OnClick I put my event handler and it works, so in your case i tried to handle the event like this
<a onClick=linkClick(' + cpid + ')">'+tmpName+"</a>
I'm using the Infobox plugin for Google Maps V3 API (http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html)
Is there anyway too close the infobox when the user clicks outside the infobox like on the map?
it's actually way easier if you have your infowindow as a global variable, or at least hold one variable that represents the single infobox you want to add at a convenient place.
edit: just to clarify: it should not be window.myInfoBox for example. With global I mean a single point where you reference your infobox
google.maps.event.addListener(map, 'click', function() {
if(infowindow){
infowindow.close();
}
});
that's all :-)
You will want to use addListener()
http://code.google.com/apis/maps/documentation/javascript/events.html#EventListeners
You can adapt the code found here:
google.maps.event.addListener(_point.popup, 'domready', function() {
//Have to put this within the domready or else it can't find the div element (it's null until the InfoBox is opened)
$(_point.popup.div_).hover(
function() {
//This is called when the mouse enters the element
},
function() {
//This is called when the mouse leaves the element
_point.popup.close();
}
);
});
Src:
Google Maps API v3 Event mouseover with InfoBox plugin
You can detect a map click with this:
google.maps.event.addListener(map, 'click', function() {
});
Infobox API:
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/reference.html
This maybe useful for you..
var inside = false;
$('#foo').live('mouseenter',function(){
inside=true;
}).live('mouseleave', function(){
inside=false;
});
$("body").mouseup(function(){
if(!inside) $('#foo').remove();
});