Part 1: Browser key events
To implement keylogging with js, you need to pay attention to the three key event types of the browser, namely keydown, keypress and keyup, which correspond to the three event handles of onkeydown, onkeypress and onkeyup respectively. A typical keypress will generate all three events, in order keydown, keypress, and then keyup when the key is released.
Among these three event types, keydown and keyup are relatively low-level, while keypress is relatively advanced. The so-called advanced here means that when the user presses shift + 1, keypress parses the key event and returns a printable "!" character, while keydown and keyup only record the shift + 1 event. [1]
However, keypress is only effective for some characters that can be printed. For function keys, such as F1-F12, Backspace, Enter, Escape, PageUP, PageDown, and arrow directions, the keypress event will not be generated, but keydown and keyup can be generated. event. However, in FireFox, function keys can generate keypress events.
The event objects passed to the keydown, keypress, and keyup event handlers have some common properties. If Alt, Ctrl, or Shift are pressed together with a key, this is represented by the event's altKey, ctrlKey, and shiftKey properties, which are common to FireFox and IE.
Part Two: Compatible Browsers
Any js that involves browsers must consider browser compatibility issues.
Currently, the commonly used browsers are mainly based on IE and based on Mozilla. Maxthon is based on the IE kernel, while FireFox and Opera are based on the Mozilla kernel.
2.1 Initialization of events
The first thing you need to know is how to initialize the event. The basic statement is as follows:
function keyDown(){}
document.onkeydown = keyDown;
When the browser reads this statement, it will call the KeyDown() function no matter which key is pressed on the keyboard.
2.2 Implementation methods of FireFox and Opera
The implementation of programs such as FireFox and Opera is more troublesome than IE, so I will describe it here first.
The keyDown() function has a hidden variable - generally, we use the letter "e" to represent this variable.
function keyDown(e)
The variable e represents a keystroke event. To find which key was pressed, use the which attribute:
e.which
e.which will give the index value of the key. The method of converting the index value into the alphanumeric value of the key requires the use of the static function String.fromCharCode(), as follows:
String.fromCharCode(e.which)
Putting the above statements together, we can get which key was pressed in FireFox:
Copy the code code as follows:
function keyDown(e) {
var keycode = e.which;
var realkey = String.fromCharCode(e.which);
alert("Keycode: " + keycode + " Character: " + realkey);
}
document.onkeydown = keyDown;
2.3 Implementation method of IE
The program of IE does not need the e variable. Use window.event.keyCode instead of e.which. The method of converting the key index value into the real key value is similar: String.fromCharCode(event.keyCode). The program is as follows:
Copy the code code as follows:
function keyDown() {
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
alert("Keycode: " + keycode + " Character: " + realkey);
}
document.onkeydown = keyDown;
2.4 Determine browser type
We have learned above how to obtain key event objects in various browsers. Now we need to determine the browser type. There are many methods, some are easier to understand, and some are very clever. Let’s talk about the general method first: that is Use the appName attribute of the navigator object. Of course, you can also use the userAgent attribute. Here, appName is used to determine the browser type. The appName of IE and Maxthon is "Microsoft Internet Explorer" , and the appName of FireFox and Opera is "Netscape", so a code with a relatively simple function is as follows:
Copy the code code as follows:
function keyUp(e) {
if(navigator.appName == "Microsoft Internet Explorer")
{
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
}else
{
var keycode = e.which;
var realkey = String.fromCharCode(e.which);
}
alert("Keycode: " + keycode + " Character: " + realkey);
}
document.onkeyup = keyUp;
A simpler method is [2]:
Copy the code code as follows:
function keyUp(e) {
var currKey=0,e=e||event;
currKey=e.keyCode||e.which||e.charCode;
var keyName = String.fromCharCode(currKey);
alert("Key code: " + currKey + " Character: " + keyName);
}
document.onkeyup = keyUp;
The above method is more clever. Let me explain it briefly:
First of all, the code e=e||event; is for compatibility with browser event object acquisition. The meaning of this code in js is that if the hidden variable e exists in FireFox or Opera, then e||event returns e. If the hidden variable e does not exist in IE, then event is returned.
Secondly, currKey=e.keyCode | There are which and charCode attributes in Opera, and there are keyCode and which attributes in Opera.
The above code is only compatible with the browser, obtains the keyup event object, and simply pops up the key code and key characters. However, a problem arises. When you press a key, the character keys are all in uppercase, and when you press the shift key, the displayed The characters are very strange, so the code needs to be optimized.
Part 3: Code Implementation and Optimization
3.1 Key code and character code of key event
The key codes and character codes of key events lack portability between browsers. For different browsers and different case events, the storage methods of key codes and character codes are different.....
In IE, there is only one keyCode attribute, and its interpretation depends on the event type. For keydown, keyCode stores the key code. For keypress events, keyCode stores a character code. There are no which and charCode attributes in IE, so the which and charCode attributes are always undefined.
The keyCode in FireFox is always 0. When the time is keydown/keyup, charCode=0, which is the key code. When the event keypress occurs, the values of which and charCode are the same, and the character code is stored.
In Opera, the values of keyCode and which are always the same. In the keydown/keyup event, they store the key code. In the keypress time, they store the character code, and charCode is not defined and is always undefined.
3.2 Use keydown/keyup or keypress
The first part has introduced the difference between keydown/keyup and keypress. There is a general rule that the keydown event is most useful for function keys, while the keypress event is most useful for printable keys [3].
Keyboard logging is mainly for printable characters and some function keys, so keypress is the first choice. However, as mentioned in the first part, keypress in IE does not support function keys, so keydown/keyup events should be used to supplement it.
3.3 Code implementation
The general idea is to use the keypress event object to obtain key characters, and use the keydown event to obtain function characters, such as Enter, Backspace, etc.
The code implementation is as follows
Copy the code code as follows:
!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD><TITLE>js keystroke recording</TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="Yu Shangren">
<META NAME="Keywords" CONTENT="js keystroke recording">
<META NAME="Description" CONTENT="js keystroke recording">
</HEAD>
<BODY>
<script type="text/javascript">
var keystring = "";//Record key string
function $(s){return document.getElementById(s)?document.getElementById(s):s;}
function keypress(e)
{
var currKey=0,CapsLock=0,e=e||event;
currKey=e.keyCode||e.which||e.charCode;
CapsLock=currKey>=65&&currKey<=90;
switch(currKey)
{
//Block backspace, tab, carriage return, space, direction keys, and delete keys
case 8: case 9:case 13:case 32:case 37:case 38:case 39:case 40:case 46:keyName = "";break;
default:keyName = String.fromCharCode(currKey); break;
}
keystring += keyName;
}
function keydown(e)
{
var e=e||event;
var currKey=e.keyCode||e.which||e.charCode;
if((currKey>7&&currKey<14)||(currKey>31&&currKey<47))
{
switch(currKey)
{
case 8: keyName = "[Backspace]"; break;
case 9: keyName = "[Tabulation]"; break;
case 13:keyName = "[Enter]"; break;
case 32:keyName = "[space]"; break;
case 33:keyName = "[PageUp]"; break;
case 34:keyName = "[PageDown]"; break;
case 35:keyName = "[End]"; break;
case 36:keyName = "[Home]"; break;
case 37:keyName = "[arrow key left]"; break;
case 38:keyName = "[arrow key up]"; break;
case 39:keyName = "[arrow key right]"; break;
case 40:keyName = "[arrow key down]"; break;
case 46:keyName = "[Delete]"; break;
default:keyName = ""; break;
}
keystring += keyName;
}
$("content").innerHTML=keystring;
}
function keyup(e)
{
$("content").innerHTML=keystring;
}
document.onkeypress=keypress;
document.onkeydown =keydown;
document.onkeyup =keyup;
</script>
<input type="text" />
<input type="button" value="Clear records" onclick="$('content').innerHTML = '';keystring = '';"/>
<br/>Please press any key to view the keyboard response key value: <span id="content"></span>
</BODY>
</HTML>
Code analysis:
$(): Get dom based on ID
keypress(e): implements the interception of character codes. Since function keys need to be obtained using keydown, these function keys are blocked in keypress.
keydown(e): Mainly realizes the acquisition of function keys.
keyup(e): Display the intercepted string.