e.stopPropagation() and jQuery.hover() - javascript

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.

Related

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'

How to trigger code wrapped in one event with another onclick event

Have this code wrapped in HOVER Event...
$("#div_ID").hover(function() {
// perform stuff here...
}
);
I'd like to trigger the above when I click a link using the ONCLICK Event...
$("anchor_ID").click (function() {
$("div_ID").trigger('hover'); // Not sure if this is even correct
}
);
It's not working though. How can I accomplish this? Is it even possible?
Using JQuery only on FF v16, IE8, and GC v23
How about this:
var dosomething = function() {
// perform the stuff here
}
$('#div_ID').hover(dosomething);
$('anchor_ID').click(dosomething);
But if you are set on using .trigger, your problem might be that you forgot to include # before div_ID. And change hover to mouseenter (the "hover" function in jQuery is just a shortcut for "mouseenter" -- credit to #FabrícioMatté for catching that) That is:
//change this:
$('div_ID').trigger('hover');
//To this:
$('#div_ID').trigger('mouseenter');
Same might apply to anchor_ID, but I won't know unless you post your HTML.
Update: another suggestion from #FabrícioMatté: the this keyword inside of dosomething might be a bit confusing when you call it as shown above, so watch out for it. The this keyword will work differently than using .trigger, so it's just a heads up....
hover is not an event so you can't trigger it. .hover() is just a shorthand which attaches mouseenter and mouseleave handlers.
$("#anchor_ID").click(function() {
$("#div_ID").trigger('mouseenter');
});
Fiddle
Note that .hover when passed a single argument will attach the function to both mouseenter and mouseleave so you can trigger either of these.
I'd recommend attaching the handler with mouseenter instead of hover if you intend to execute the handler only when users move their mouse above the div.

Can mouseenter and click event exist together?

I am wondering if mouseenter and click event can exist together and they can both exist to TRUE when checked with:
if ((evt.type === 'mouseenter') && (evt.type === 'click'))
It is because when I mouse over the link, the mouseenter triggers (set to TRUE) and even when I clicked on it, the hover is still shown. Probably they could exist together but I'm no expert on this.
If someone can give insights, I would appreciate it a lot.
Also how can I trigger the click event during the mouseenter event?
The mouseenter event fires when the mouse enters the control. The click event fires when the mouse is clicked. They are two separate events which call two separate event handlers. If you click just as the mouse enters the element they will be called within a short timespan of one another but they are still two distinct events.
It is also important that you differentiate between the mouseenter and the mouseover events. mouseenter fires when the mouse physically enters an element, whereas mouseover fires continually while the mouse remains over an element.
While you cannot trigger the click event per se, you can call the same function that is called by the click event handler. For example if you have this:
var myfunc = function (e) { ... }
document.getElementById("id").onclick = myfunc;
Then you could simply call myfunc directly and you would get the same result as if the mouse was clicked.
They can 100% exist together, and this is a great question with no good answer... When you're on a mobile device, a mouseenter event will be thrown on tap... If you are also detecting onclick as well as mouseenter, then there will be a discrepancy between mobile devices and desktop machines.
It's kind of hard to solve such a small issue at the moment.
const x = document.getElementById('some_node')
x.onclick=(e)=>{
e.stopPropagation()
// this logic will be triggered on click for both desktop and mobile
}
x.onmouseenter=(e)=>{
e.stopPropagation()
// this logic will be triggered on click for mobile only (but will
//have already been triggered on desktop when cursor entered node)
}
The only workaround I came up for this, and I think it's pretty clever, is using a eventlistener for taps/touches. The order/priority that these events are fired goes: touch > mouseenter > click.
Since the touch event is fired first, you can add a touch event listener (which will only register on a mobile device), and change a variable that prevents the mouseenter event from being triggered (which is the logic that would generally be conflicting with the onclick logic)... like this:
let isMobile = false
x.addEventListener('touchstart',(e)=>{
isMobile = true
}, false);
Then your mouseenter would need to look like this:
x.onmouseenter=(e)=>{
e.stopPropagation()
if(!isMobile){
// this logic will no longer cause a conflict between desktop and mobile
}
}
they can exist on the same object, think a button with a hover state and then a click action. The click event, though will only read the click event since the enter event actually occurred earlier.
You can create a var like mouseIsOverand set it to true when the enter event fires. I can be safely assumed, though that if a click happens the mouse is over the same target.
The two events may happen at the same time, but they will still be processed on after the other. So the if you posted will never evaluate to true.
If you look at your code again you can see that it doesn't make sense. How can something be X and Y at the same time? It can't.
for the first question i think u got an answer....
however, for Also how can I trigger the click event during the mouseenter event?
u can use trigger() function..
http://jsfiddle.net/PDhBW/2/
if u want to read more about trigger
here is the link
http://api.jquery.com/trigger/
With Jquery event delegation, You can use binding multiple events at once
$('#IdElement').on('mouseenter click', function () {
//Your Code
});
http://jqfundamentals.com/chapter/events

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.

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

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.
)}

Categories

Resources