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.
Related
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
I have an <input> element that can either have the focus set via code, or as the result of a mouse click.
If the user clicks on the input, then the click event handler will fire - all well and good. If the element receives the focus via some other way (e.g. via code) then I want to manually trigger the click event so that the handler will also fire.
I could do this:
$elem = $('input');
$elem
.on('focus', function() { $(this).trigger('click') })
.on('click', function() { alert('Clicked!') });
However, this will result in click handler being fired twice; once for the click event and once for the focus event.
Is there any way to selectively trigger the click handler only if the focus was not received as the result of a click event?
UPDATE
This is a very simplified version of my problem, so I can't do things like bind both handlers to the focus event etc. I'm trying to merge two third-party pieces of code.
The .trigger() function adds a property isTrigger in the event object to identify that the event was triggered by its usage. Although, it is not documented the property is still present in jQuery 1.8.3 but it seems to only be used internally.
Anyways, you can make use of the extraParameters parameter to add a custom property to the event object. For instance,
$(this).trigger('click', {
isTrigger: true
});
It will keep the compatibility with isTrigger even if it is gone in a future release.
After doing some more research it appears that there is no way of guaranteeing which event will fire first: click or focus. (There doesn't seem to be a standard that dictates the order of events.)
This means that when the focus event fires there's no way to determine if a click event will or will not be triggered by the browser shortly afterwards.
I managed to solve the issue by using setTimeout() to run a test about 100ms after the focus event fired to check if the click event had fired. The third-party code that I was using (bound to the click event) added an extra class to the <input>, so I was able to check for that.
You can tap into the mousedown event which fires before the focus event. When you click a focusable object the order of events is as follows... mousedown, focus, mouseup, click.
You could set a flag in the mousedown event and then check for it in the focus event to see if the focus came from a mouse click. Obviously make sure to clear the flag in the focus event handler. Every application is different, but tapping into the mousedown event allows you to figure out a solution.
Here is a JSFiddle demonstrating the order of events... http://jsfiddle.net/ek7v7/
$elem = $('input');
$elem
.on('focus', function() { alert("Focused!") })
Focus can be fired by focusing the input by using tab, clicking it, or by using .focus()
Is there a reason for on('click', ...)?
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.
I am using jquery 1.3.2.
I am registering two handlers as follows:
$(document).onmousedown(dochandler)
$('#element').click(elemhandler)
When I click on #element both the handlers get called. And surprisingly dochandlers gets called before elemhandler. I have tried changing the orders of above handler registration, but no use.
Both handlers are returning false to avoid event propagation.
My understanding is elemhandler should get called when #element is clicked. Since I am returning false from elemhandler, the dochandler should not be called. And even if dochandler gets called, it shouldn't get called before elemhandler.
Any idea what might be wrong here?
Thanks.
They are two separate events so returning false on one wont affect the other. The click event is fired when the mouse button is released: http://api.jquery.com/click/
dochandler is called prior elemhandler because mousedown event happens prior click event and as poswald mentioned, they are two separate events and they don't affect each other.
The click event means the mouse buttons is pressed down and released. The mouseDown is only pushed down. For example if you do drag and drop, the mouseDown event is fired, then any number of mouseMove, and finally mouseUp.
So yes, mouseDown is fired before click. And as others said they are different events so they don't affect each other.
Any ideas why this doesn't work, or how to make it work? I want to remove the "onmouseover" and "onmouseout" events so they are basically disabled and at the same time change the background color. Then when the user clicks on another element I want to reassign the mouse events back to the element. Right now the onmouse events don't get disabled at all, the background doesn't change, etc.
Here's how I call the function:
Here's the function:
$(document).ready(function(){
$(".maximize").toggle(
function(){
$("#property_bg").unbind("onmouseover");
$("#property_bg").unbind("onmouseout");
$("#property_bg").toggleClass("body_bgcolor");
},
function() {
$("#property_bg").bind("onmouseover", function() {
swap_class("property_bg","body_bgcolor")} );
});
});
Thanks for the help.
Remove the "on" from the event names. Then it'll work.
on your events, take out the 'on'... just mouseover or mouseout...
I found out the real problem in the following two threads for anyone who comes along with a similar problem I will add them here:
How do I unbind "hover" in jQuery?
Why this unbind doesn't work?
The problem was solved by not hard coding the mouse events in the HTML, but rather binding them in the document.ready 1st. In order to "unbind" and event, the event has to be "binded" by jquery.
Also, "mouseover" didn't work for some reason I couldn't figure out, but when I put "mouseenter" and "mouseleave" as suggested in one of the posts above it worked. I've never heard of "mouseenter" or "mouseleave", but ... it works now.
Good luck!