Leaflet on mouseout event not firing when changing iconUrl - javascript

I am experiencing an issue with leaflet and it's mouseout event.
In the code below, sometimes (particulary if you move the mouse fast), the mouseout event is not triggered. The Mouse out ! doesn't appear in the console.
I found out that this behaviour is related to the icon replacement. A simple layer.setStyle works every time. (Here I use the leaflet-gpx plugin but it works the same way as leaflet's IconUrl or shadowUrl)
// This works every time
gpxPath.on('mouseover', function (e) {
var layer = e.target;
layer.options.marker_options.startIconUrl = 'myHoverIconStartUrl';
layer.options.marker_options.endIconUrl = 'myHoverIconEndUrl';
layer.reload();
});
gpxPath.on('mouseout', function (e) {
console.log('Mouse out !')
var layer = e.target;
/* those two lines below cause the issue */
layer.options.marker_options.startIconUrl = '';
layer.options.marker_options.endIconUrl = '';
layer.reload();
});
I know that the mouseout event sometimes causes issues like this one, but in this particular case I am forced to use the leaflet events and I am a little bit out of ideas.

Are you trying to make markers display a different icon on hover?
It's hard to tell without an example, but what I think is happening is:
Your mouseoutevent isn't getting triggered reliably because the mouseover event is ran continuously, as long as your mouse is positioned on it, every time the icons rebuild.
You may notice this if you add a console.log in that function as well. You can happen to move off while it is rebuilding, so you don't trigger the mouseout event reliably.
If so, try something like:
line.once('mouseover', function () {
//switch to icons
});
line.on('mouseout', function () {
//clear icons
//Prevent mouseover event from firing continuously if/when the icon changes
line.once('mouseover', function () {
//switch to icons
});
});

Related

Remove touchpointer in javascript

I was trying to make a webapp with html elements that will move form div to antoher div when clicked but also I want to be able fire event when users hold that element for more than a second. So I have this code
$(document).on("click",'.card', function() {
var card=$(this).parent();
if(card.parent().attr('id')==="options"){
card.appendTo("#choice");
}
else{
card.appendTo("#options");
}
});
var timeoutId = 0;
$('.card').on('pointerdown', function() {
timeoutId = setTimeout(showModal, 1000);
}).on('pointerup mouseleave', function() {
clearTimeout(timeoutId);
});
And it is doing almost fine. The problem occures when the element is clicked. It is appended to different div as it should but the mobile pointer is still on it so when I try to fire 'hold' event on another element it is not working for the first time since 'pointerup' event from previous element is firing right after 'pointerdown' event (So you need to try to hold next element twice).
I've dealt with it by adding a simple boolean flag in click event function so it is blocking next first call of 'pointerup' event but this is a very ugly solution.
Do you have any ideas how can i improve this? Maybe there is a way to call 'pointerup' event manually after click?
Removing 'mouseleave' event and adding 'pointerleave' instead fixed the problem.
Not really sure how 'mouseleave' event was fired on mobile device though.

Avoid custom overlay click event when map is panning (google maps API)

Related to this question: 'Make custom overlay clickable (Google Maps API 3)' and related also to my comment in the same question (posted here to give it more visibility and because I think is other problem).
I have added a click listener to my overlay polygon but now I have the problem that when user wants to pan the map and clicks on an overlay to do that, when the mouse button is released the click event is triggered. Obviously I don't want to execute the onclick action when I just want to pan the map. Any elegant solution for this issue?
Here is an example of the issue: panning/click issue.
Check out this updated fiddle here: http://jsfiddle.net/9gvsq3od/5/
Basically I added this code:
var dragging = false;
google.maps.event.addDomListener(this.path_, 'mousedown', function (evt) {
dragging = false;
});
google.maps.event.addDomListener(this.path_, 'mousemove', function (evt) {
dragging = true;
});
// onclick listener
google.maps.event.addDomListener(this.path_, 'click', function (evt) {
if (dragging) { return false;}
alert('clicked on path');
});
The click event is only triggered when the mouse button is released so code sets a variable dragging to true when the mouse moves. The first mousedown handle resets the dragging variable, since there is no "mousestop" event, we need to reset the state when beginning a new interaction instead.

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