jQuery .hover(function{}) only on actual hover - javascript

I'm familiar with jQuery but i have one little setback. I would like the function to be called only when i just hover the element, and not when im already hovering it and i slightly move the mouse.
I simply want the function to be called only if i'm entering the area of the element from outside of it.
I hope this makes sense.
Any ideas?

The hover method binds an event handler for mouseenter and one for mouseleave, so it won't trigger any event whenever the mouse is moved within the element.
It's the mousemove event that is used for that. Perhaps you are binding that also somewhere?
If you only want to handle the event when the mouse enters, and not when it leaves, used the mouseenter method instead of hover.

maybe you need mouseenter and not the whole hover event
$(div).mouseenter()

Yes hover will bind a mouseenter and a mouseleave to your selector:
try:
$(div).mouseenter(function(){
//Do whatever you want to do on your mouse enter.
)}

Related

keep mouse over active if hovering over another overlapping element

I've got a DOM structure like the one below. These to elements are overlaping. On hover, video start to play. Unfortunately, when I hover over .showsOnHover, mouseover and mouseout repeatedly fire one after another making .showsOnHover blink and video stutter.
What should I do to instruct browser to treat hovering over .showsOnHover as one continuous hover?
.html
<video (mouseover)="mouseover()" (mouseout)="mouseout()"></video>
<div [hidden]="!hovering" class="showsOnHover"></div>
.ts
mouseover(e){
this.hovering = true;
this.video.play();
}
mouseout(e){
this.hovering = false;
this.video.stop();
}
The issue is that when showsOnHover is shown, it covers up the video, which makes it mouseout, so it hides the div, then the hover event triggers again, and it shows the div, and it just loops over and over very rapidly.
You essentially will want to do one of the following:
Put the mouseover and mouseout events on both the video and the showsOnHover elements, perhaps do it on a containing parent div element. This way the mouseout event won't be triggered when it's shown; instead it will only trigger when you leave the larger containing element.
Add pointer-events: none; to your .showsOnHover class in the CSS. This makes that div transparent to mouse events. However, this could cause issues if you wanted to run any click events off that button.
Change mouseover to mouseenter as mentioned in Ram's answer
create a parent div and fire the same event on that,
<div class="parentDiv" (mouseenter)="mouseover()" (mouseleave)="mouseout()">
<video></video>
<div [hidden]="!hovering" class="showsOnHover"></div>
</div>
Use mouseenter instead of mouseover
mouseenter(e){
this.hovering = true;
this.video.play();
}
[.mouseover()] can cause many headaches due to event bubbling. For
instance, when the mouse pointer moves over the Inner element in this
example, a mouseover event will be sent to that, then trickle up to
Outer. This can trigger our bound mouseover handler at inopportune
times. See the discussion for .mouseenter() for a useful alternative.
Please see What is the difference between the mouseover and mouseenter events?
Use (mouseenter) and (mouseleave) instead of (mouseover) and (mouseout)

How do we make use of `mouseover` and `mouseout` event?

As JQuery document says, I have converted many lines mouseover to mouseenter because it does not fire more than once.
http://api.jquery.com/mouseover/
mouseover fires when the pointer moves into the child element as well
mouseenter fires only when the pointer moves into the bound element.
Even hover event works as mouseenter and mouseleave, not as mouseover and mouseout.
It makes me wonder why there is mouseover event if mouseenter can do it all.
For me, mouseover gets fired unpredictably when you move mouse around on an element. It seems really dependent on the depth of child elements.
Is there a good use-case of mouseover and mouseout, which needs to fire multiple times?
That I know of, there is no use case for mouseover/mouseout at all. The only reason they exist is because these events are triggered by browsers because they are in the standard DOM event list. mouseenter and mouseleave are not standard events, but they are jQuery-specific constructs.
I suppose a use case would be if you wanted the event to trigger when moving the mouse over and out of the children of the element that the events are bound to. I can't think of anything specific, but at least this functionality is available. If only mouseenter/mouseleave existed, you wouldn't have a choice in the matter.
From http://code.jquery.com/jquery-1.9.1.js:
jQuery.each({
mouseenter: "mouseover",
mouseleave: "mouseout"
}, function( orig, fix ) {
/* content snipped */
Speculation: the reason why the creators of jQuery created the mouseenter and mouseleave non-standard events is because their behavior works as you would expect the mouseover/mouseout events to work (i.e. without regard for descendants).
Because the event contains coordinates of cursor.
So if you need to track mouse coordinates under the target, you have to use 'mouseover'

Jquery focusout on div

I have two divs, one called "mainDesign" and a box called "div1".
When "div1" is clicked, focusin is called and the border-color changes.
"div1" can only focusout if "mainDesign" is clicked.
The script works but "mainDesign" needs to be clicked twice in order for it to work, after it has focused out, the script works perfectly.
Any ideas?
Code: http://jsfiddle.net/v3DWf/14/
Thanks.
Rewrote using mousedown and stopPropagation(): http://jsfiddle.net/patrickmarabeas/v3DWf/20/
Haha, looks like Royce Feng beat me to it.
I removed focusout(), as it seems to be an unnecessary step...
Is this acceptable?: http://jsfiddle.net/patrickmarabeas/v3DWf/15/
EDIT: switched the functions around, seems to work as intended now: http://jsfiddle.net/patrickmarabeas/v3DWf/17/
You can switch to using .mousedown() and stopping propagation in the inner one.
http://jsfiddle.net/v3DWf/18/
Try this:
$("#div1").focusin(function() {
$(this).css("border-color","#ff9900");
});
$("#mainDesign").mousedown(function(){
setTimeout(function(){
if (!$("#div1").is(":focus"))
$("#div1").css("border-color","#999999");
}, 100);
});
The timeout is necessary because the mousedown will fire before the div is blurred.
Well the problem is that you've nested the .mousedown() event within the .focusout() event.
So what is happening here is that when the focusout event is triggered, you are then attaching the .mousedown event to the mainDesign div. Let me re-iterate that again, the .mousedown event will NOT be attached until the focusout event has triggered.
Then once the .mousedown event is attached, the next time you mousedown in the mainDesign div, the event will fire which is why it is currently taking you two clicks.
So the easiest solution is to simply get rid of the .focusout event.

e.stopPropagation() and jQuery.hover()

Is there a way to have both of these work together or do I have to try using the mouseenter and mouseleave instead?
You can use event.stopPropagation() with .hover(), but you're actually using mouseenter and mouseleave with .hover() anyway. If you provide 1 function to .hover(), it runs on both events, if you provide 2 functions, the first is the mouseenter handler, the second is the mouseleave handler.
However, this may not be what you're after...since mouseenter doesn't fire when entering a child, that's actually specifically why it exists, mouseout will fire when entering a child. You can see that's there's no difference in a demo here, hover from top to bottom, comment and uncomment out the .stopPropagation(), it makes no difference...because the event doesn't bubble to the parent.
However if you are using mouseover and mouseout, then it would matter, like this:
$("li").mouseover(function(e) {
$(this).addClass("red").parents().removeClass("red");
}).mouseout(function(e) {
$(this).removeClass("red");
});​
Now we have a bubbling problem, because the event bubbles right up, adding the class to the parent we just removed it from, see a demo of the problem here. However if we stop that bubble, with the .stopPropagation(), we get the desired effect, like this:
$("li").mouseover(function(e) {
$(this).addClass("red").parents().removeClass("red");
e.stopPropagation();
}).mouseout(function(e) {
$(this).removeClass("red");
});​
You can see in this demo how this works differently.
In short: yes event.stopPropagation() works with .hover(), but most likely, it's not exactly what you're after.

onMouseButtonUp

I need some way to find out when the user released the mouse button - something like keyUp - but for the mouse...
Any ideas?
PS: I want to mimic: active pseudo-class and my idea was to do something() on mouse press, and UnDoSomething() on mouse button up ... now ... if you got a better solution - hit me up! :)
The event is onmouseup: http://www.w3schools.com/jsref/event_onmouseup.asp
Or mouseup if you're calling element.addEventListener or using one of the JavaScript frameworks that drop the "on" part of the name.
Update:
If you want to listen for any mouse up event, you'll need to register an onmouseup listener on the page body in your onmousedown callback, and then unregister the onmouseup listener from within the onmouseup callback (so it only happens once).
If you're using jQuery, this can be accomplished with the one() function.
Of course, if the user moves their mouse outside of the browser window before releasing their button, you won't get the mouseup event. I'm not sure if there's anything you can do about that.
The according event is called onmouseup... You can see a sample implementation here:
http://www.webmonkey.com/codelibrary/JavaScript_Event_-_Mouseup
What you might be looking for is something like:
<button onmouseup="alert('hello world');">Say hello world on mouse-up</button>

Categories

Resources