Using jQuery, I often like to use mousedown and mouseup events in conjunction for pushable buttons.
However, in every case I've used the mouseup event, binding the click event instead seemed to produce identical results.
Is there any substantial difference between the two methods below?
// Method 1
$('.myButton').bind('click', callback);
// Method 2
$('.myButton').bind('mouseup', callback);
Please note I'm seeking a technical explanation on the differences between using both methods. This has no relation to the question that has been flagged as a dupe: Differentiate click vs mousedown/mouseup
With a mouseup event, you can click somewhere else on the screen, hold down the click button, and move the pointer to your mouseup element, and then release the mouse pointer.
A click event requires the mousedown and mouseup event to happen on that element.
The normal expectation is that a click requires both the mousedown and mouseup event, so I'd recommend the click event.
From the possible duplicate, it appears that mouseup and mousedown events can also be caused by mouse buttons other than the left click button. Which is very different from what a generic user would expect.
My understanding is that "click" hides lots of complexities (such as making sure that mousedown/up occur on the same element, cancelling with ESC/right click). Using "click" over "mousedown/up" should be preferred.
One scenario where "click" does not seem to work when app updates content very often in such a way that underlying DOM elements get replaced. In this case "click" will not be triggered and it might result in poor customer experience.
I think Mouse Down and Mouse Up events give you further control over the click event. It divides the click event into two more events so that more details can be coded for each event. Click event restricts the mouse click and force you to code both the events in the same function.
You can understand this restriction if you ever try to make your own dragging behavior.
Dragging needs a mouse-down event to start a drag behavior. You cannot do it with click event. And since you need a separate mouse-down event. The requirement of a separate mouse-up event becomes obvious.
Once the dragging starts ( you have not yet release the mouse button) you need the object to change position as per the cursor position. This too needs to be coded only in mouse-down event.
However you can use click event too if we could change the way how people drag the objects. For example click-1 starts the drag and click-2 stops the drag and puts the object on another position. But there are two problems I see:
It does not look natural. As in the real world we are in habit of
pressing the object and dragging it.
It can be process intensive to move heavy graphics just by clicking and mouse-move.
I would like to add to the other answers that click event works on touch-enabled devices while mouseup / mousedown do not (obviously because there's no "mouse")
Note that there's a 300ms delay on touch devices with the click event.
The biggest difference that affects the way I code is: the click event on an a HTML tag is responsible for changing the URL. In contrast, the mousedown and mouseup events will not acheive this
Related
I have divs, which are made to textinput fields by a plugin. Also those divs are draggable.
Right now, I have reached, that if you drag the div, it gets dragged, and if you just click on it, it gets a ".focus()".
The problem is now, that if I click it once, i get a focus on it. But the cursor jumps to the beginning of the line.
What I want, is the cursor on the place, I clicked.
How can I do this with jquery? Thanks
EDIT (My JS Code):
$('.mydiv').click(function(){
//actually, it does not focus on "$(this)" but on a div inside ".mydiv" which
//is generated by the plugin
$(this).focus();
})
You could consider listening for mouseup and mousedown instead of click, which would help you distinguish between which event the user is performing. Like, if there is a mouse down event, and the user moves the mouse before a mouseup event, then you're in "drag" mode. If there's a mouseup event, and the user is not in "drag" mode, then the user has clicked, and you can fire a focus event.
That's the approach I would take without knowing more about what you're doing.
The truth is that you have a considerably more complex interface requirement than most, meaning you're going to have to give the computer more instructions to determine what to do :)
I have a Canvas which responds to mousedown events on it. I am then adding an input element to the DOM, and absolutely positioning this so it is over the canvas.
After then user has clicked on the input element, and entered some text, they then click back to the canvas. My problem is that this first click merely sets the focus back to the canvas, but is not registered as a mousedown event on the canvas element.
What can I do to make sure that the first click is registered?
How are you attaching the events? This should "just work", unless there are extenuating circumstances.
Here's an example:
http://jsfiddle.net/bSpe4/
Depending on what your code looks like, giving your canvas a tab index value may also help.
theCanvas.tabIndex = 0; // might fix your particular issue
I just had exactly this problem. I needed to listen for both left and right clicks and was using a mousedown.
In case anyone finds this as I just have. I "solved" it by attaching the event to mouseup rather than mousedown.
That way the focus happens when on mousedown and the event triggers on mouseup which is fine for what I'm doing.
I have a fairly large html page and I've noticed that my click-to-show/hide process appears a little retarded.
I've also discovered that if I use "mouseenter" in place of "click", the response is almost instantaneous (as opposed to 2 seconds when I use "click").
$("button.showhide").click(function() { $("#"+$(this).attr("id")+"-1").toggle() });
versus
$("button.showhide").mouseenter(function() { $("#"+$(this).attr("id")+"-1").toggle() });
Is there any way to make the click event as fast as the mouseenter event?
Thanks.
Edit:
Does the following help in explaining this behaviour?
(There's no mention of a "javascript event" for mouseenter.)
.click()
Bind an event handler to the "click" JavaScript event, or trigger that event on an element.
.mousedown()
Bind an event handler to the "mousedown" JavaScript event, or trigger that event on an element.
.mouseenter()
Bind an event handler to be fired when the mouse enters an element, or trigger that handler on an element.
You should use a delegate to trigger your events(from jQuery 1.7 use on method for events binding) :
$("button").on('click','.showhide',function(){/*...*/});
You could improve the speed of the event handling, but that depends on the html markup.
For instance, if all of your showhide buttons are grouped in a certain div, and some other buttons are in other scattered all over the body, you should use something like this :
$("button-container-selector").on('click','button.showhide',function(){/*...*/});
I think that the time to process
function() { $("#"+$(this).attr("id")+"-1").toggle();
is exactly the same in the two cases, it's just that mouseenter triggers much earlier than click and so you think it's faster.
The only thing i could think of is that you have realy a lot of click handlers, but i think you really nead a lot to slow down things
EDIT - Try doing
$('body').on("click", "button.showhide", function() { $("#"+$(this).attr("id")+"-1").toggle());
By reading all previous answers, and the behaviour explained in the question, I think that there might have been a key piece of information missing. Was your test was happening in a tablet or a touch-enabled device by any chance?
Some touch-enabled browsers or devices will slow down click events to allow for a delay, so the user can start a gesture instead of issuing a click. This would explain why, in your case, "mousedown" or "click" are slower than "mouseenter", which in a touch device happens as soon as you touch the element being monitored.
If this is the case, what I would do to improve responsiveness and be compatible in different types of devices, is binding both "mousedown" and "touchstart" (compatible with touch-enabled devices) to the code that must execute after the mouse press (or screen touch).
In your case:
$("button.showhide").bind('touchstart mousedown', function() {
$("#"+$(this).attr("id")+"-1").toggle()
});
I hope this helps.
Which events are the most resource intensive to have attached? Is a mouseover "worst" than a click? Are there any events that are known to be really harsh on the browser? I have my sights on IE7 mainly, as we are seeing performance issues there. We use event delegation where we can.
Or, how can I profile events which are actually running to determine which have the greatest impact on performance at runtime?
I'm interested in the events themselves, please don't tell me I need to go look into what my functions are doing in those events. Problems may exist there, but that's not my question.
So, to start with, events that fire more often can be more troublesome. So a mouseover event, which fires "continuously" as the mouse moves over an element, could cause a performance impact more easily than a click event, which can only fire as fast as the user can click.
However, it's the code you put in your handler that will have the real performance impact.
If firing speed is an issue, check out the excellent jQuery throttle/debounce plugin: https://github.com/cowboy/jquery-throttle-debounce
I'd imagine a callback's intensity is proportional to how many times it's called.
Events like mouseover or deviceorientation are more demanding than a click or similar 'one time' event.
The more an event have to check (and then throw) the more it consumes i.e. order from the max to the min:
mousemove throws an event at any move
mouseover throws an event at each move if pointing on a relevant item
mouseenter have to watch where is the cursor to then trow something
mouse click only throws an event when you click…
What is the difference between jQuery's mouseout() and mouseleave()?
The mouseleave event differs from mouseout in the way it handles event bubbling. If mouseout were used in this example, then when the mouse pointer moved out of the Inner element, the handler would be triggered. This is usually undesirable behavior. The mouseleave event, on the other hand, only triggers its handler when the mouse leaves the element it is bound to, not a descendant. So in this example, the handler is triggered when the mouse leaves the Outer element, but not the Inner element.
Source: http://api.jquery.com/mouseleave/
There can be times when mouseout is a better choice than mouseleave.
For example, let's say you've created a tooltip that you want displayed next to an element on mouseenter. You use setTimeout to prevent the tooltip from popping up instantly. You clear the timeout on mouseleave using clearTimeout so if the mouse leaves the tooltip won't be displayed. This will work 99% of the time.
But now let's say the element you have a tooltip attached to is a button with a click event, and let's also assume this button prompts the user with either a confirm or alert box. The user clicks the button and the alert fires. The user pressed it fast enough that your tooltip didn't have a chance to pop up (so far so good).
The user presses the alert box OK button, and the mouse leaves the element. But since the browser page is now in a locked state, no javascript will fire until the OK button has been pressed, meaning your mouseleave event WILL NOT FIRE. After the user presses OK the tooltip will popup (which is not what you wanted).
Using mouseout in this case would be the appropriate solution because it will fire.
jQuery API doc:
mouseout
This event type can cause many headaches due to event bubbling. For instance, when the mouse pointer moves out of the Inner element in this example, a mouseout event will be sent to that, then trickle up to Outer. This can trigger the bound mouseout handler at inopportune times. See the discussion for .mouseleave() for a useful alternative.
So mouseleave is a custom event, which was designed because of the above reason.
http://api.jquery.com/mouseleave/
Event Mouseout will trigger when mouse leaves the selected element and also when mouse leaves it's child elements also.
Event Mouseleave element will trigger when pointer will leave the selected element only.
Reference: W3School
I encountered a similar problem using plan Javascript instead of jquery, but they're some how related and I'll leave my two cents in case someone else is on the search nowadays.
I was trying to use the mouseout event on a navigation menu. The parent div had a submenu composed of a list of uls elements. When I tried to navigate to the div children elements the mouseout event was fired. This was not my desired output.
From the docs
mouseout is also delivered to an element if the cursor enters a child
element, because the child element obscures the visible area of the
element.
And that was the issue.
The mouseleave event did not have this issue. Just using it made things work for me.
https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseleave_event