views:

950

answers:

6

I want to capture the Ctrl-R or F5 shortcut on the browser to prevent it from performing a browser refresh, but instead perform a custom refresh.

I was able to capture Ctrl-R on Safari and FF using:

document.onkeypress = function(e){
      if ((e.ctrlKey || e.metaKey) && e.keyCode == 114) // Ctrl-R
    e.preventDefault();
}

But that doesn't work on IE. Is there any way to do this on IE?

Update: For people who are asking why I am doing this in the first place: I just wanted to do a custom app refresh, but wanted to avoid having a "refresh" button because I kinda discourage using the refresh (We have a full page flex app). We ended up switching to F8 because F5 was just too hard to get working on all browsers.

+2  A: 

Open JavaScript

http://www.openjs.com/scripts/events/keyboard_shortcuts/

For certain keys (F1, F4), you have to open a new browser window, without the address bar.

Example

Open a new window, without adornments:

window.open( 'webpage.html', 'TLA', 
'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=800,height=665' );

JavaScript to use the library:

var FALSE_FUNCTION = new Function( "return false" );

/**
 * Called to disable F1, F3, and F5.
 */
function disableShortcuts() {
  // Disable online help (the F1 key).
  //
  document.onhelp = FALSE_FUNCTION;
  window.onhelp = FALSE_FUNCTION;

  // Disable the F1, F3 and F5 keys. Without this, browsers that have these
  // function keys assigned to a specific behaviour (i.e., opening a search
  // tab, or refreshing the page) will continue to execute that behaviour.
  //
  document.onkeydown = function disableKeys() {
    // Disable F1, F3 and F5 (112, 114 and 116, respectively).
    //
    if( typeof event != 'undefined' ) {
      if( (event.keyCode == 112) ||
          (event.keyCode == 114) ||
          (event.keyCode == 116) ) {
        event.keyCode = 0;
        return false;
      }
    }
  };

  // For good measure, assign F1, F3, and F5 to functions that do nothing.
  //
  shortcut.add( "f1", FALSE_FUNCTION );
  shortcut.add( "f3", FALSE_FUNCTION );
  shortcut.add( "f5", FALSE_FUNCTION );
}

Inside webpage.html:

<body onload="disableShortcuts();">
Dave Jarvis
I tried this out and it worked on IE8, Chrome, Safari, Opera and FF for me - for the F5 key.
toby
I have used it on FF 3.0, IE6, and IE7.
Dave Jarvis
+1  A: 

YUI has a key handler that will work across all browsers

http://developer.yahoo.com/yui/examples/container/keylistener.html

I think the problem with the above code is that IE doesn't pass the event to the function. It puts it in a global variable called window.event.

I suggest trying the YUI key listener, it will be a pretty clean solution and you don't need to use the whole library, just the pieces you need.

Zoidberg
+1  A: 

I beleave document.body.onbeforeunload is the way. You can even prevent user from leaving the page with that. Just not sure about how to detect if its a refresh or if he's actually surfing to somewhere else (document.location maybe?)

Havenard
+3  A: 

There's no solid way to override the function-keys in browsers.

Internet Explorer has certain keys that can't be overridden, and certain keys which - even when overridden - still executes default behavior--like the F11 key, which switches to full-screen mode, and the F1 key which opens up a help-window.

Chrome does not allow you to use key-events at all.

FireFox is the most benign, but still sketchy--like Internet Explorer; there are still some keys and default behavior you cant override.

And finally.. Opera.. Which is about as difficult as Internet Explorer.

And the default behavior is different from version to version. It's like walking into a mine-field.. Blindfolded.. :)



You wanting to override CTRL+R / F5 smells like bad design. What problem are you trying to solve?

roosteronacid
+1 for "smells like bad design".
Ölbaum
@Dave Jarvis: Are you sure this works in Internet Explorer 8? I've had no luck doing just that.
roosteronacid
@roosteronacid: On IE8, I had to make a one-line fix: add "var code;" after the line: "var func = function(e) {". IE8 is seems to be stricter with js.
toby
in shortcuts.js, that is.
toby
@roosteronacid: toby verified it works.
Dave Jarvis
This is not necessarily bad design. Consider moving to a web based applications from a desktop application. Imagine having hundreds of users who have been trained to use F5 for "User Lookup". Imagine that all the other function keys have been assigned, as well as most of the regular keyboard shortcuts. Making people click a menu for "User Lookup" would significantly impact data entry time (1 second vs 0.1 seconds adds up over 8 hours by 10 workers by 5 days a week).
Dave Jarvis
All that said, putting in a custom refresh on the client, rather than trapping the refresh on the server, smells like bad design.
Dave Jarvis
@Dave Jarvis: Considering the fact that this can't be done across all A-grade browsers, it's bad design. I agree with the idea though.
roosteronacid
+2  A: 

Since the "how" has already been covered, I thought I'd mention that you have to be aware of the limits of using Javascript for something like this.

For example, in Safari (and possibly others), if you can get to the browser's Search input field, you can still issue shortcut key commands, but it's out of the scope of your Javascript. If the user does that, any key-event-eating code that you wrote will not be invoked, and the keypress will go through just fine.

So the solutions you find may work, but will almost universally be defeatable in some way by just using basic browser functions.

Luke Rinard
A: 

for f11 on ei add checkkey on onkeydown event for the body (onkeydown='return checkKey(event)' )

function checkKey(e) { var alt = e.altKey; var key = e.keyCode; var type = e.srcElement.type; ctrl = event.ctrlKey

if ( alt || ((key == 8)&&(type != "text" && type != "textarea" && type != "password")) || (ctrl&&(key == 82)) || (key == 122) ) { event.keyCode = 0; e.keyCode = 0; event.returnValue = false; return false; }

    return true;

}

max