How to call an action after click() in Jquery? - javascript

I want to load an image and some other actions after I click a certain DOM element, but I want to load them AFTER the clicking action finished.
Here is a code example:
$("#message_link").click(function(){
if (some_conditions...){
$("#header").append("<div><img alt=\"Loader\"src=\"/images/ajax-loader.gif\" /></div>");
}
});
The problem is that the if condition executes before the click action have finished(Or at least that is my impression). I need that the If condition executes after the click action has finished. Can some one please tell me a solution?
Thanks :)

setTimeout may help out here
$("#message_link").click(function(){
setTimeout(function() {
if (some_conditions...){
$("#header").append("<div><img alt=\"Loader\"src=\"/images/ajax-loader.gif\" /></div>");
}
}, 100);
});
That will cause the div to be appended ~100ms after the click event occurs, if some_conditions are met.

If I've understood your question correctly, then you are looking for the mouseup event, rather than the click event:
$("#message_link").mouseup(function() {
//Do stuff here
});
The mouseup event fires when the mouse button is released, and does not take into account whether the mouse button was pressed on that element, whereas click takes into account both mousedown and mouseup.
However, click should work fine, because it won't actually fire until the mouse button is released.

you can write events on elements like chain,
$(element).on('click',function(){
//action on click
}).on('mouseup',function(){
//action on mouseup (just before click event)
});
i've used it for removing cart items. same object, doing some action, after another action

Related

Trigger an event IMMEDIATELY on mouse click, NOT after I let go of the mouse?

I have probably a dumb question but here we go:
When you trigger a function with onclick="function()" or addEventListener onclick the function gets triggered only AFTER I click AND let go of the mouse.
Is there any way to trigger a function IMMEDIATELY on clicking an html element, NOT after clicking and letting go.
I want this to work anywhere I click on the body element.
The click event is triggered after the entire mouse action has been completed.
Use mousedown instead of click.
document.addEventListener("mousedown", function(){
console.log("You did it!");
});
Please check the mousedown event: https://www.w3schools.com/jsref/event_onmousedown.asp

Is it possible to detect a mouse click on a page on every element?

I want to trigger a function if a user clicks anywhere on the page, even clicking on no element or link. Is it possible?
The extension runs only on youtube.com so I can't add every element on the page to the trigger and I assume that every page has different element's ids.
Emmanouil Chountasis is correct, you can use the code at "Detect left mouse button press" to detect a left mouse click crossbrowser.
To the heart of your question, I think what you're looking for is Event Delegation. In jQuery,
// Select a wrapper for the events
$('body')
// Whenever any element in the <body> is clicked
.on('click', '*', function (evt) {
// Emmanouil Chountasis's suggestion would be called right here
if (isLeftClick(evt)) {
// ... do stuff
}
});
See http://learn.jquery.com/events/event-delegation/
Reed's answer works fine, but it triggers the action multiple times. I found this solution that only works on left mouse triggers and executes once per click.
$("body").unbind().click(function() {
//Do Stuff
});

Single user action firing two events - second event doesn't trigger

I’m running into this issue where a single action by the user is supposed to trigger two events but it only triggers the first one.
The scenario:
A user enters some text into a special field that modifies the layout on focusout , after entering the text, without leaving the field, they click a button.
What’s happening?
I have a focusout event on a text box and click event on a button. What I see is the focusout event gets fired but the click event never does.
I’ve encapsulated this in a jsfiddle:
http://jsfiddle.net/fCz6X/13/
$('#theText').focusout(function (){
$("#focusevent").text("Focusevent");
console.log("focus");
});
$('#theButton').click(function (){
$("#clickevent").text("Clickevent");
console.log("click");
});
So if you click in the text field then click the button I’d expect both events to fire, but we only see the focus out event.
I put in a temporary fix for this by having the mousedown event fire the button instead of a click event (this fires before the focusout event) but that is causing some other behaviors and issues that I don’t want to see. Due to those I think optimal solution is finding a way to get the focusout and click events to both fire. Does anyone have thoughts on how to fix this problem?
Edit: After seeing initial responses I dug a little deeper, the issue here is that the focusout event is changing the page layout which very slightly pushes the location of the button down. The click event triggers after the focusout is done but since the button is no longer in the exact same location, nothing happens.
Here is an updated fiddle that shows my problem
http://jsfiddle.net/fCz6X/11/
It's because you're calling alert - the focusout event fires, but before the browser recognizes you've clicked the button, the alert box blocks it.
Change your event handler to console.log or something else that's non-obtrusive and you'll be ok.
It is the Alert that is blocking.
Some browser security prevents firing too many window.alert at the time.
When trying with other triggers, it looks. You may try console.log()
$('#theText').on("focusout",function (){
$("#theText").val($("#theText").val()+"flb");
});
$('#theButton').on("click",function (){
$("#theText").val($("#theText").val()+"but");
});
I believe this is because the focusout event fires first, executing the handler, and the alert then prevents the browser from recognizing the click.
Try again with console.log instead of alert - it's less invasive.
As Joe said, the blocking alert call is what is breaking the event. Using a non-blocking call you will see both events.
If you really need to perform an alert like this, though, you can defer calling 'alert' until later using setTimeout()
$('#theText').focusout(function (){
setTimeout(function() { // alert after all events have resolved
alert("focus left text box");
}, 0);
});
Edit: In your updated fiddle the reason the click event never fires is because no click event occurs. If you move the button out from under the mouse on mousedown, there is no followup mouseup which is what initiates the 'click' event.
You may need to reconsider other aspects of your design. Your solution of using 'mousedown' is the best you can achieve because it's the only event that actually occurs.

Blur event stops click event from working?

It appears that the Blur event stops the click event handler from working? I have a combo box where the options only appear when the text field has focus. Choosing an option link should cause an event to occur.
I have a fiddle example here: http://jsfiddle.net/uXq5p/6/
To reproduce:
Select the text box
Links appear
Click a link
The blur even occurs and the links disappear
Nothing else happens.
Expected behavior:
On step 5, after blur occurs, the click even should also then fire. How do I make that happen?
UPDATE:
After playing with this for a while, it seems that someone has gone to great lengths to prevent an already-occurred click event from being handled if a blur event makes the clicked element Un-clickable.
For example:
$('#ShippingGroupListWrapper').css('left','-20px');
works just fine, but
$('#ShippingGroupListWrapper').css('left','-2000px');
prevents the click event.
This appears to be a bug in Firefox, since making an element un-clickable should prevent future clicks, but not cancel ones that have already occurred when it could be clicked.
Other things that prevent the click event from processing:
$('#ShippingGroupListWrapper').css('z-index','-20');
$('#ShippingGroupListWrapper').css('display','none');
$('#ShippingGroupListWrapper').css('visibility','hidden');
$('#ShippingGroupListWrapper').css('opacity','.5');
I've found a few other questions on this site that are having similar problems. There seem to be two solutions floating around:
Use a delay. This is bad because it creates a race condition between the hiding and the click event handler. Its also sloppy.
Use the mousedown event. But this isn't a great solution either since click is the correct event for a link. The behavior of mousedown is counter-intuitive from a UX perspective, particularly since you can't cancel the click by moving the mouse off the element before releasing the button.
I can think of a few more.
3.Use mouseover and mouseout on the link to enable/disable the blur event for the field. This doesn't work with keyboard tabing since the mouse is not involved.
4.The best solution would be something like:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
Unfortunately, $(document.activeElement) seems to always return the body element, not the one that was clicked. But maybe if there was a reliable way to know either 1. which element now has focus or two, which element caused the blur (not which element is blurring) from within the blur handler. Also, is there any other event (besides mousedown) that fires before blur?
click event triggers after the blur so the link gets hidden. Instead of click use mousedown it will work.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
Other alternative is to have some delay before you hide the links on blur event. Its upto you which approach to go for.
Demo
You could try the mousedown event instead of click.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
This is clearly not the best solution as a mousedown event is not achieved the same way for the user than a click event. Unfortunately, the blur event will cancel out mouseup events as well.
Performing an action that should happen on a click on a mousedown is bad UX. Instead, what's a click effectively made up of? A mousedown and a mouseup.
Therefore, stop the propagation of the mousedown event in the mousedown handler, and perform the action in the mouseup handler.
An example in ReactJS:
<a onMouseDown={e => e.preventDefault()}
onMouseUp={() => alert("CLICK")}>
Click me!
</a>
4.The best solution would be something like:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
Unfortunately, $(document.activeElement) seems to always return the
body element, not the one that was clicked. But maybe if there was a
reliable way to know either 1. which element now has focus or two,
which element caused the blur (not which element is blurring) from
within the blur handler.
What you may be looking for is e.relatedTarget. So when clicking the link, e.relatedTarget should get populated with the link element, so in your blur handler, you can choose not to hide the container if the element clicked is within the container (or compare it directly with the link):
$('#ShippingGroup').blur(function(e)
{
if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
// Alt: (!e.relatedTarget || $(e.relatedTarget) == $('.ShippingGroupLinkList'))
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
}
(relatedTarget may not be supported in older browsers for blur events, but it appears to work in latest Chrome, Firefox, and Safari)
If this.menuTarget.classList.add("hidden") is the blur behavior that hides the clickable menu, then I succeeded by waiting 100ms before invoking it.
setTimeout(() => {
this.menuTarget.classList.add()
}, 100)
This allowed the click event to be processed upon the menuTarget DOM before it was hidden.
I know this is a later reply, but I had this same issue, and a lot of these solutions didn't really work in my scenario. mousedown is not functional with forms, it can cause the enter key functionality to change on the submit button. Instead, you can set a variable _mouseclick true in the mousedown, check it in the blur, and preventDefault() if it's true. Then, in the mouseup set the variable false. I did not see issues with this, unless someone can think of any.
I have faced a similar issue while using jQuery blur, click handlers where I had an input name field and a Save button. Used blur event to populate name into a title placeholder. But when we click save immediately after typing the name, only the blur event gets fired and the save btn click event is disregarded.
The hack I used was to tap into the event object we get from blur event and check for event.relatedTarget.
PFB the code that worked for me:
$("#inputName").blur(function (event) {
title = event.target.value;
//since blur stops an immediate click event from firing - Firing click event here
if (event.relatedTarget ? event.relatedTarget.id == "btnSave" : false) {
saveBtn();
}
});
$("#btnSave").click(SaveBtn)
As already discussed in this thread - this is due to blur event blocking click event when fired simultaneously. So I have a click event registered for Save Btn calling a function which is also called when blur event's related Target is the Save button to compensate for the click event not firing.
Note: Didnt notice this issue while using native onclick and onblur handlers - tested in html.

How to tell if a mouseup is going to be followed by a click event?

Is there any way to know, in a jQuery onmouseup handler, if the event is going to be followed by a click event for the same element?
I have an event handler for a menu hyperlink which unbinds itself when the user either clicks on an element or "drops" (as in drag-n-drop) on an element. I want to avoid prematurely unbinding the handler on mouseup if a click is coming next.
I realize I can track mousedown and mouseup events myself or otherwise hack up a solution (e.g. wait 50 msecs to see if a click comes soon), but I was hoping to avoid rolling my own implementation if there's something built-in for this purpose.
There is nothing built-in because it's really specific to your needs. Thus, there would kilometers of code and documentation to maintain if jQuery would handle any combination of clicks, long clicks, moves, etc.
It's also hard to give you a snippet that satisfies your needs, but a setTimeout is usually the first step to take, with something like that :
obj.mouseup = function (){
obj.click = action; // do action
setTimeout ( function() {
obj.click = functionOrigin // after 500 ms, disable the click interception
}, 500);
};
you can use $(selector).data('events') for that
$('div').mouseup(function(){
if($(this).data('events').click){
console.log('Has a click event handler')
}
});

Categories