GMarker onmouseout event fired too soon - javascript

Here's the situation:
On my Google Map, I'm trying to open an html info window whenever the user moves its mouse over a GMarker.
This window should be closed when the pointer is out of the marker.
GEvent.addListener(my_marker, "mouseover", function() {
MaCarte.openInfoWindowHtml(new GLatLng(my_marker.getLatLng().lat()+0.002, my_marker.getLatLng().lng()+0.001),"some text");
});
GEvent.addListener(my_marker, "mouseout", function() {
if((MaCarte.getInfoWindow().getPoint().lat() == my_marker.getLatLng().lat()+0.002)
&& (MaCarte.getInfoWindow().getPoint().lng() == my_marker.getLatLng().lng()+0.001))
MaCarte.closeInfoWindow();
});
What happens is that the onmouseout event is fired too soon, so the info window opens and closes right after it.
My guess is that the mouse no longer is over the marker but over the info window causing the onmouseout to be fired.
How can I do to let the info window open until my pointer is actually out of the marker?

I would use a timer and variable that dictates whether it's ok to close the window. Basically, have a timer start in the mouseover event and that timer changes a variable. The mouseout event then only closes the window if it's ok to close
like
GEvent.addListener(my_marker, "mouseover", function() {
timer.start()
MaCarte.openInfoWindowHtml(new GLatLng(my_marker.getLatLng().lat()+0.002, my_marker.getLatLng().lng()+0.001),"some text");
});
GEvent.addListener(my_marker, "mouseout", function() {
if (okToClose){
if((MaCarte.getInfoWindow().getPoint().lat() == my_marker.getLatLng().lat()+0.002)
&& (MaCarte.getInfoWindow().getPoint().lng() == my_marker.getLatLng().lng()+0.001))
MaCarte.closeInfoWindow();
}
});
This doesn't directly answer your question, but it will work as a workaround.
Hope it helps!
Chris

One thing that can happen is that opening a Google infowindow can cause the map to pan in order for the whole of the infowindow to be visible in the viewport and not obscured by any of the controls. The pan motion can cause the marker to move out from underneath the mouse, causing a mouseout. One way to deal with that effect is to use the undocumented {suppressMapPan:true} option on your infowindow. Another way to deal with it is to use a non-Google infowindow that doesn't pan the map.
Another thing that can happen is that you might have an incorrectly designed custom GIcon. If the .infoWIndowAnchor is too low, the infowindow itself could steal the mouseover, causing a mouseout on the marker. You can deal with that by setting the y coordinate of the .infoWindowAnchor more negative.
However, when you get it all working, you'll probably find that a map that opens the infowindow on marker mouseover is awkward to use. You get a better user interface, and one that some users will already be familiar with, by only displaying a small tooltip on mouseover, and only displaying the full infowindow when the marker is clicked.

It happens in other areas of JavaScript/HTML also.
Sometimes you have to bind a handler to an event but only after handled the current one because it gets called immediately...
So instead of
GEvent.addListener(...);
I do
setTimeout(function() { GEvent.addListener(...); }, 1);
To give the current thread the time to finish up handling the current event.
Hope this helps.

Related

Enabling event propogation effectively in Google Maps API v3

As covered in an existing question, I have a piece of code which (nice and simply) keeps a div updated with the current location of the cursor like so.
function updateLocation(e) {
document.getElementById('current_coordinate').innerText = e.latLng.toUrlValue(6);
}
It works brilliantly until the cursor moves over an overlay. The overlay consumes the event so the event listener I have defined on the map never fires.
google.maps.event.addListener(map, 'mousemove', updateLocation);
Questions:
Must I redefine that listener on every overlay I create or is there simpler way?
If I must define listeners on every overlay, roughly how many overlays may I have without performance suffering?
The overlay is interactive and so setting clickable to false is not an option.
See also these discussions that indicate this is a bug - as yet unfixed:
https://groups.google.com/forum/#!topic/google-maps-js-api-v3/z_K7hxKhonI
https://groups.google.com/forum/?hl=en#!topic/google-maps-js-api-v3/mM0mB9FcyAU

How to fire action when ANY Google Map Event Has Been Fired

I am implementing an app using Google Maps API 3. I would like to know what is the best implementation in dealing with this problem. I want to execute an action once ANY event in Google Map has been fired. Currently, what I am doing is that I call the function every time a specific event is called. I find this redundant and I have to make a listener for all of the events. So, is there a way to generalize this where I can do the following:
google.maps.addListener(everything_on_the_map_canvas, 'ANY_EVENT', function(event) {
foo();
})
function foo(){
//do something here
}
Thank you.
If the user decides to continue with map operations, they will have to move the mouse over the map to do anything. So you could simply trap a mousemove.
google.maps.event.addListener(map, 'mousemove', function(event) {foo();})
If the user can manipulate the map without moving the mouse over the map, then you will need to listen to other events.
bounds_changed will cover most eventualities with zoom and pan, heading and the like
maptype_id_changed
But that's only three instead of all of them. If the bounds don't change when the tilt does (and you can change tilt from outside the map) you may need to listen for tilt_changed as well.

HTMLDivBalloon - Google Earth API Question

I have a problem using balloons in google earth.
I have some markers on the map, upon clicking on a marker, a balloon popup is shown containing some data, now when I click on the close button of that balloon, the click event of the map is also triggered which is really annoying as I have a handler attached with the map click event.
I tried everything including using event.stopPropagation() in the 'beforeclose' event of the htmlDivBalloon but still nothing works.
Anyone has an idea about that ?
Best Regards
John Tadros
The chances are you are not handling the default event or you are not screening which objects the event acts in the handler "attached with the map click event". You haven't shown any code, so it is hard to say exactly how to fix it - but a generic way to handle this is as follows.
// listen for mousedown on the window
google.earth.addEventListener(ge.getWindow(), 'mousedown', function(e) {
var type = e.getTarget().getType();
if (type == 'KmlPlacemark') {
// prevent the default event for placemarks, stop Propagation
e.preventDefault();
e.stopPropagation();
} else if(type == 'GEGlobe') {
// do something with the globe...
}
// etc...
});

Javascript event handling for Google Maps

I am using google maps + javascript + php in my application.
I want to know two things:
In google maps,
does moveend event ALWAYS gets fired
AFTER zoomend/dragend (whichever of
two) event occurs.
When I click zoom icon on google map
or scroll the mouse wheel to zoom,
the zoomend event gets fired more
than once. If I zoom in one step
using + icon on map, the zoomend
event gets fired twice or sometimes
more. any possible loophole.
And so want to know how to stop further event propogation in javascript. (remember I need not use clearListeners as it will forever ignore event handler which is undesirable).
Thank you.
I set up listeners for 'moveend', 'zoomend', and 'dragend' to try it out.
GEvent.addListener(map, "moveend", function() { console.log('moveend'); });
GEvent.addListener(map, "zoomend", function() { console.log('zoomend'); });
GEvent.addListener(map, "dragend", function() { console.log('dragend'); });
It appears that 'moveend' always fires after 'zoomend' or 'dragend'.
However, no events ever fired more than once at a time. Maybe you accidentally set up two simultaneous listeners. You shouldn't need to use stopPropagation or cancelBubble.
you could try just reuturning false or null from the event.
If that doesn't work trying using "event.cancelBubble = true" or "event.stopPropagation"

Detect if mouse is over an element when page loads with Javascript

I have an image that I want to have trigger certain behaviors when the mouse is over, I have a mouseover and mouseout method, but if you happen to have your mouse over the image when the page loads, the mouseover method never fires until you leave the image and come back over it.
Is there a way to detect if the mouse is over an element on the fly without the mouse having to be off of the element and then come over the element to trigger the JS mouseover event? Like is there a document.getElementById("blah").mouseIsOver() type function in Javascript?
I believe this is possible without any action from the user. When your page loads, bind the mouseover event to your image and hide your image (i.e. using CSS display:none). Use setTimeout() to show it again in a few milliseconds (10 should be enough). The even should be fired.
If you don't want to cause the 'flick' effect on your image, you may try using some temporary element instead, attaching event to it, and delegating the event onto your image.
I have no idea if this is cross-browser solution, but it worked from my Firefox 3.0 console ;)
You could use the mousemove event. That would trigger anytime the user moves a mouse; so the only instance of the trigger not firing would be if the user does not move the mouse at all, which should be rare.
The only problem with this is that the event would fire anytime the mouse would move over your image, so you would get a LOT of those events while over the component. What you would probably need to do is implement some sort of flag within your method when the event fires. You turn on the flag when the event first fires, and you turn it off when you leave the component.
This is less than ideal, but I think this will probably satisfy your problem scenario. The following is some quick pseudo code on what that solution might look like, I think it should work.
<img src="blah.png" onmousemove="JavaScript:triggerOn(event)" onmouseout="JavaScript:triggerOff(event)"/>
...
<script type='text/javascript'>
var TriggerActive = false;
function triggerOn(e){
e = e||window.e;
if( !TriggerActive){
TriggerActive = true;
// Do something
} else {
// Trigger already fired, ignore this event.
}
}
function triggerOff(e){
e = e||window.e;
if(TriggerActive)
TriggerActive = false;
}
</script>
You can find some great mouse event information including browser compatibility notes here.
Use document.querySelectpor and onload/onready events.
var a = document.querySelector('#a:hover');
if (a) {
// Mouse cursor is above a
}
else {
// Mouse cursor is outside a
}
There is no way to get the mouse coordinates aside from listening for mouse events, namely mousemove, mouseover etc. However, these events are very sensitive in the sense that moving the cursor by just one pixel is enough to trigger them, so having the cursor hover over your image while perfectly still should be somewhat unusual.

Categories

Resources