2
function test(){    
    alert("This message should show");
    window.location.href = "http://www.google.com";
    alert("This message should NOT show");
}
<href="#" onClick=test()>Click Me</a>
  • Step through using Firefox(v8): The second message does NOT show.
  • Step through using chrome (v15, v16): BOTH alerts show.

Chrome blows past the redirect and continues through the rest of the call stack (in this case, it finishes the onClick) before redirecting.

  • No JavaScript Errors.
  • All extensions disabled.
  • I'm using a blank html file with no external files loaded.

Does anyone know of a way to get chrome to execute the window.location change immediately?

pimvdb
  • 151,816
  • 78
  • 307
  • 352
Adem Miller
  • 53
  • 1
  • 7

4 Answers4

2

Pretty sure the specs give you no guarantees for this one, so I'm not too surprised. The obvious solution would be to throw an exception right after. Assuming you don't have catch blocks littered around your code, that ought to work:

throw "Aborting, redirecting you.";

(Yes, it's ugly. Sorry!)

Edit: fiddles: without throw, with throw

Gijs
  • 5,201
  • 1
  • 27
  • 42
  • Yes, it is UGLY ... but it WORKS =) Any better answers out there? I would still like a more complete answer from the google guys though. Why in the world would the js engine NOT redirect immediately?? ~sigh~ – Adem Miller Dec 14 '11 at 21:47
  • 2
    Because it's not the JS engine redirecting. It's the DOM implementation which redirects you, the JS engine doesn't give a pig's tail. Chrome seems to have made the assignment asynchronous (probably gives you better speed), which means the JS engine just continues to run its stuff. See also this question: http://stackoverflow.com/questions/7787788/setting-location-href-twice-in-chrome – Gijs Dec 14 '11 at 21:49
  • Looks like throw is maybe the only option - I didn't even know this happened so good to know. http://stackoverflow.com/questions/550574/how-to-terminate-the-script-in-javascript – aknosis Dec 14 '11 at 22:06
  • That question points to a problem, though: event handlers will still run after a throw, even if it is not caught. If you're using a library (like jQuery), unbinding all bound event handlers is probably a bit easier... This is interesting, so I'll have a look if I can find a snippet to do that... – Gijs Dec 15 '11 at 11:00
  • Hmm, looks harder than I thought. Of course, something like $('*').unbind() would do, but it might be slow... – Gijs Dec 15 '11 at 11:04
  • I just tried $('*').unbind() and it IS slow.... not a solution. Oddly enough, my ~original~ redirect code is nested inside a jqueryui autocomplete ajax call (which is why it takes SOOO long to complete when chrome blows past the redirect).... Anyway, the time dramatically reduces (like from 5sec to 0.5sec) when I remove a confirm() just prior. I'm still hunting for a righteous solution. – Adem Miller Dec 15 '11 at 19:38
  • How are you measuring the time? If it includes the time it takes for the user to click inside the `confirm` dialog, the big difference makes sense, but says nothing about your code. – Gijs Dec 15 '11 at 23:10
  • If there's a confirm box I count time from after "ok" clicked. If not then I count time from link clicked. The link click is ~5x faster every single time. I will investigate further, but I imagine that it's just a matter of the call stack getting bigger for whatever reason. The original problem persists for sure: Chrome fails to redirect on command. – Adem Miller Dec 16 '11 at 00:11
  • Hmm. Any pending XHRs with success/error handlers at that time? Might be that aborting them / waiting with firing them / removing the success/error handlers helps, although by now I'm shooting in the dark... Good luck, in any case! – Gijs Dec 16 '11 at 08:01
0

There is a better way to do this.

function test(){    
alert("This message should show");
return true;
alert("This message should NOT show");
}

<href="http://www.google.com" onClick="return test()">Click Me</a>

Optionally, you can use a confirm to control whether or not this action can be performed on click. Blame Google for trying to mess with functional standards, no other browser forces you to do this.

K_Cruz
  • 729
  • 6
  • 17
0

I was just trying the same thing: redirect using JS. In the PHP script I have, if a certain condition is true, I just end the script with a die function, echoing a script tag with the redirect code:

die("<script type='text/javascript' charset='utf-8'>\n".
    "window.location.href='http://'+window.location.hostname+'/newdir/newfile.html';\n".
    "</script>\n");

This was not working and I tried to execute the code from the console and it works from there. I assumed it was something about timing, so I added a setTimeout to the redirect:

die("<script type='text/javascript' charset='utf-8'>\n".
    "var configURL = 'http://'+window.location.hostname+'/newdir/newfile.html';\n".
    "setTimeout('window.location.href = configURL', 500);\n".
    "</script>\n");

This patch works for now but I think there should be a better way to do it.

0

You could add a return

function test(){    
    alert("This message should show");
    window.location.href = "http://www.google.com";
    return;
    alert("This message should NOT show");
}
Darcy
  • 5,228
  • 12
  • 53
  • 79