views:

1184

answers:

5

I have written the following javascript code to catch F5 key press and prevent the user from refreshing:
(I understand this is not a good idea but i am stuck with this whether any one likes it or not. Also the question i ask pertains to why the script below does not work with safari 4 but works for other browsers.)

var fn = function (e)
{

    if (!e)
        var e = window.event;

    var keycode = e.keyCode;
    if (e.which)
        keycode = e.which;

    var src = e.srcElement;
    if (e.target)
        src = e.target;    

    // 116 = F5
    if (116 == keycode)
    {
        // Firefox and other non IE browsers
        if (e.preventDefault)
        {
            e.preventDefault();
            e.stopPropagation();
        }
        // Internet Explorer
        else if (e.keyCode)
        {
            e.keyCode = 0;
            e.returnValue = false;
            e.cancelBubble = true;
        }

        return false;
    }
}

// Assign function to onkeydown event
document.onkeydown = fn;

The above code works perfectly for IE 6,7 and 8, from Firefox 2.0 onwards and also in Chrome. However it does not work for Safari 4 for windows. Pressing the F5 key refreshes the document. The funny thing is that in Safari the code gets inside the if (e.preventDefault) part above but for some reason its not preventing the default action i.e. refreshing the page.

Is this a bug with Safari 4 or is there some safari specific code i need to write?

Thanks

+9  A: 

Never try anything that hinders a user's normal action with a browser. Even if you do this using javascript he can disable the script and then continue the page refresh.

If you need to prevent the action made on a refresh then handle it in server side.

rahul
+5  A: 

It seems like you are trying to obstruct the user from doing something that your code cannot handle easily, e.g. stopping them 'purchasing item X' twice by hitting refresh, or hitting your site too often by holding F5 to annoy you.

I'd suggest other solutions such as cookies/state management or blocking client IPs if you are preventing abuse.

JBRWilkinson
+2  A: 

+1 to everyone else saying “don't do this”. It's just not at all feasible. There are many other ways of refreshing the page... on my browser at least: the toolbar button*; ctrl-R; right-click-reload; ctrl-T to get a tab bar then right-click-on-tab-reload; and so on. Tell your client it's impossible and get on with something actually useful.

*: trying to hide the browser chrome is also not allowed by my browser, because it's a really bad idea. You are opening yourself up to phishing attacks by eliding the essential indicators that tell the user that they are really on your site.

bobince
A: 

Yes, it appears to be a bug with Safari 4 Windows. You cannot stop CTRL+F either.

However, opening an alert stops it, but that is a rough trade off.

jedierikb
A: 

To the people who are saying, "don't do this": You aren't helping. There is ALWAYS a side case where a rule of thumb must be broken.

For example, the client I'm working with has a system that has a major piece of their testing application built off of a second browser window, which goes full screen, no toolbars, bookmarks, or any other window options, and disables all keys that aren't directly affected by the testing environment. In this case, it is valuable to the user, who is likely someone of low technical skill, to be able to take the test without inadvertently hitting F5 and reloading a large, client-side series of questions with all of their previous answers erased. The questions are client side because preloading allows the test to be run on a low-bandwidth connection, like those found in the third world.

From what I can tell of this Safari-only issue (Chrome, another Webkit-based browser, doesn't have this problem), even the alert box will not keep the browser from refreshing. The alert shows, then the page refreshes normally.

Nothing I've tried seems to block the key. I have read that this is considered a defect with Safari, and that a certain build number of Safari should contain a fix, but as of the time I'm writing this, this hasn't been implemented in the most recent version of Safari for Windows. I've tested this on the Mac, and it seems to be fixed on that platform.

WRast