why is 'mouseleave' not triggered when triggering 'mouseenter' programmatically? - javascript

I'm writing a Next.JS app, and creating a useHover() hook to handle hover events via Javascript by using 'mouseenter' and 'mouseleave' events, and
I noticed that when I triggering 'mouseenter' programmatically:
let mouseenter = new Event('mouseenter');
refElement.current.dispatchEvent(mouseenter);
'mouseleave' event is not triggered anymore automatically (which I need for my logic) after leaving the element.
Why tho? Am I missing something? BTW all listeners are set correctly, everythings (mouse events) work as intended when not triggering programmatically, but for some reason, manual triggering break automatic 'mouseleave'.

Related

"mouseDown" event does not triggered on "click" In Mapbox-gl in a scenario

Good day,
In mapbox gl js latest version, I bind a couple of events like click, mousedown, mouseup and mousemove.
In mobile device, if I click, the following order of event should occur:
"mouseMove"(First)
"mouseDown"
"mouseUp"
"click"(Last)
However, in some case's only mouseMove event is occurring. I noticed that this happens only when mapboxgl popup is added on Map and my mouse cursor is above it.
It seems like in mobile when I click on the marker, firstly "mouseMove" event gets called, which shows the popup. but then the rest of the events("mouseDown", "mouseUp" and "click") gets called on popup instead and not the map.
I am confused, How can I call the callbacks that are bind on Map(MapEvents) directly?
The one hack I can do is to add setTimeout delay, so that event could go down to map first and then add popup. But I really hope, if there could be a better way of achieving this.
Any suggestion would be helpful.
Codepen(Request to please open in chrome mobile device emulator)
https://codepen.io/dollysingh3192/pen/QWKzdbO
Also, added a giphy at Dropbox(Edit with offset). Have a look!
https://www.dropbox.com/s/87bq7t762s6t6qw/Jan-17-2021%2000-13-36.mp4?dl=0

JQuery click event triggered on Chrome and FF device touch emulation?

In my Rails site, I have an element that I want to act as a link when clicked by a mouse (e.g. on a desktop), but not when touched on a touch-screen device (because there is also a hover behavior).
My understanding is that the JQuery .click event should not get triggered on a touch.
My coffeescript for setting the click handler is simply
...
$(this).click ->
location.href = url
...
(where "this" is the element in question)
I know this code works, because the click action works with the mouse. To ensure that it doesn't get triggered on a touch device, I use the device emulation in Chrome's Developer Tools to emulate a touch. However, when I do this, the method still fires and follows the link.
Is this a problem with the Chrome emulation or with my code? I want to know whether it will behave this way on real touch devices.
edit: Same thing happens with Firefox, so I'm thinking it's my code...
I realized that touch events trigger click events as well, later on in the event chain. To get the functionality I wanted, I kept the .click handler, but added a .touchstart handler where I called event.preventDefault() to short-circuit the rest of the event chain. This way, the .click handler fires for mouse clicks, but not for touches.

Which touch event should e.preventDefault() be called in to cancel a "click" on a touch device?

To prevent a click from firing, you can call e.preventDefault() in a click event handler. This lets you bind an event to mousedown, see if something happens like the mouse moving a certain distance, and if so, prevent the click when the mouse button is released.
A click handler with e.preventDefault() does not seem to prevent a click on certain touch devices however. (I am testing on an iPad mini). I have also tried calling e.preventDefault() in the touchend handler, which seems to do nothing.
Calling e.preventDefault() in the touchstart blocks the page from scrolling, and is also useless because it is too early to tell if the click should be cancelled. Only touchmove can decide if a cancel needs to occur.
The issue is, when a user drags a draggable element which is also a link, it needs to cancel the "click" of the link on fingerup. This works just fine on a desktop by cancelling the click event.
Is there an equivalent event I can cancel that stops an "armed click" from going off once the user lifts their finger up?
iOS is known to not register the click event property. This is likely due to the fact that iOS waits a little longer to determine how a click should be interpreted as:
the start of a pinching/zooming gesture
two or multiple-finger panning
the start of scrolling
the start of double tapping
a simple tap event (which we are trying to capture)
the start of touch-and-hold
Therefore, you can listen to the tap event instead, included in jQuery Mobile.
The jQuery Mobile tap event triggers after a quick, complete touch
event that occurs on a single target object. It is the gesture
equivalent of a standard click event that is triggered on the release
state of the touch gesture.
The tap event is not native, because it relies on conditionally listening upon touchstart to determine if the start and stop targets are the same: if so, jQuery Mobiel determines that it is indeed a genuine tap event and fires the custom, non-native event tap. This logic can be seen in the original source file, at line 75 onwards of ./js/events/touch.js.
An example usage is as follow:
$(selector).on('tap', function(e){
e.preventDefault();
});

Click event doesn't work properly

I've made a little experiment with Html5 canvas and Javascript events.
Unfortunately, in a certain case, the javascript click event has an unexpected behavior.
This is the fiddle of the experiment : http://jsfiddle.net/Rh4kP/10/
When you click, often there is no output in the console. I observed this on Google Chrome 22.0.1 and Firefox 14.0.1
More weird, when you comment one of the "flip" line like this :
document.getElementById(hiddenCanvas).style.display = 'block';
// document.getElementById(displayedCanvas).style.display = 'none';
or
// document.getElementById(hiddenCanvas).style.display = 'block';
document.getElementById(displayedCanvas).style.display = 'none';
Click events work propertly !
The definition of a click event is this, per the Mozilla Development Network:
The click event is raised when the user clicks on an element. The click event will occur after the mousedown and mouseup events. [emphasis mine]
In other words, your 'flip' event is firing so quickly modifying content that your mousedown and mouseup events are not happening on the same DOM element, and so click does not fire.
Try this example (derived from yours) to see this in action. You'll notice that when your click event fires, the mousedown and mouseup events happen on the same DOM element. But when it doesn't happen, it is because mousedown and mouseup are happening on different DOM elements. Another test to run is slowing down your flip/flop. With a very slow timeout, you'll have less of a chance of encountering this problem (though the chance still exists - I would recommend using mouseup)
Try using just the 'mouseup' event instead. I tested w/ your example and it seemed to consistently work.
See the If you delete a DOM element, do any events that started with that element continue to bubble? question for some more information.

canceling touchend event when touchmove starts

I have a scrollable list in my web app, using scrollability to deal with the overflow:scroll feature. although when I finish scrolling and take my finger out of the screen the event bellow also triggers.
$('li').live('touchend', function (e) {
//...
});
The thing is that I only would like this event above to fire when the action there's no touchmove event before that.
it is possible to suppress a touchend event from inside the touchmove event?
so it simulates better the iOS UITableView component? where when touchmove starts it cancels the target for touchend
Set a flag in touchmove which can be tested in touchend and if the flag is set, just skip the functionality and possibly preventDefault() (either way, reset the flag at the end).

Categories