1

Given I have HTML like this:

<a id="google" href="http://google.com">Google.com</a>

And JavaScript like this:

$('#google').on('click', function (e) {
  console.log("Click Click Bang Bang!");
});

When I click my google link, the click event fires and the page immediately loads the next link…

What happens if the target URL (google.com) loads before the click event finishes? If events just fire and complete irrespective of the viewable page updating/changing urls/etc then that's awesome! BUT if that's not the case, how do you ensure your click event runs to completion?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user3084728
  • 565
  • 1
  • 8
  • 16

3 Answers3

2

The console.log is synchronous call and page is redirected after the completion of the click event. If you have asynchronous call in the click event then you have to take care that your have to wait for response before leaving the page.

Adil
  • 146,340
  • 25
  • 209
  • 204
  • Thank you for answering. The last part of my question says: how do you ensure your click event runs to completion? Is there a preferred way of doing this? thanks! – user3084728 Jan 29 '14 at 04:46
  • @user3084728 it will always run before your gets redirected – Deepak Ingole Jan 29 '14 at 04:46
  • It depends, if you do not have asnc call then click event will get completed before opening a link. – Adil Jan 29 '14 at 04:48
  • 1
    For asnc call you may prevent the default link behaviour until success or failure – Adil Jan 29 '14 at 04:51
  • @adil i'm sorry but I'm a newbie. Any code examples you can provide will be really helpful. – user3084728 Jan 29 '14 at 06:00
  • If you are newbie then you do not have to worry about completion of click event unless you start using async calls in click event handler. – Adil Jan 29 '14 at 06:12
1

There's a little (lot) more to this than meets the eye.

First, you should really understand event-bubbling.
That is to say, you've set the "click" event-handler to run as soon as the <a> element has found a "click" event.

Which means that whatever handlers are given to that object will run before the element tells its parent (who will tell their parent, on and on, until you get to the top of the page).
Switching pages happens at the root-element (<html> or document.documentElement).

So on the same event, the a.onclick = function () { }; will always happen before the window.onclick = function () { }; handler, because of bubbling.

HOWEVER that only begins to scratch the surface...

If you are running async operations inside of your click-handler, and it's a click on a link, and the browser is going to change pages, then all of your async stuff (server-calls/image-loads/script-loads/etc) are ignored (or cancelled), once the browser reaches the "unload" phase (more on that, later).

You would either need to synchronize what you're doing (save to document.cookie or localStorage, instead of making AJAX calls, et cetera), or manually prevent the <a> from telling its parents what happened, using .stopPropagation() on the event object, which is passed to the event-handler.

Of course, now that it doesn't tell its parents, it will never reach window, so the page will never change...

...so now, in your handler, if you want the page to change, after you've done your async stuff, you have to manually make the page-change happen by setting window.location = googleEl.href;, and do so after you're sure all of your async work is done.

...of course, that's not the end of it... ...when the browser does want to change the page, it also fires a "beforeunload" event, and an "unload" event you can listen to from window. Again, the same async rules apply...
And to make things muddier, only most browsers fire "beforeunload", some don't bother.

So to answer your exact question:
The click-handler fires first, then a few events in between, then "beforeunload", then "unload", then the page changes.

Norguard
  • 26,167
  • 5
  • 41
  • 49
0

I would recommend redirecting through anchor after on click. therefore :

$('#google').on('click', function (e) {
  console.log("Click Click Bang Bang!");
  //This would stop from redirecting
  e.preventDefault();
  //This will take you to Google after completing the above task
  window.location.reload = "http://google.com";
});
Makrand
  • 587
  • 5
  • 14
  • Why? can you explain your reasoning please? – user3084728 Jan 29 '14 at 06:03
  • @user3084728 Sure. the reason i put e.preventDefault(); is to stop the link from executing so that you can perform all the operations you want in your click and later lead the control to the desired website after your click completes. – Makrand Jan 29 '14 at 06:10