youyoui

监听键盘鼠标事件

监听某个按键事件

当键盘上的某个键被按下时,会依次触发一次下面的事件:

  • onkeydown: 键盘按下这个动作(按下键盘)
  • onkeypress: 键盘被按住(一直按着键盘不动)
  • onkeyup: 键盘被弹起(松开键盘)

通过监听keydown事件既可以知道键盘被按下:

document.onkeydown = function(event) {
    // 键盘按下时触发
	console.log(\'key down\');
};

document.onkeypress = function(event) {
    // 键盘按住时触发
	console.log(\'key press\');
};

document.onkeyup = function (event) {
    // 键盘弹起时触发
	console.log(\'key up\');
};

// 控制台数据的顺序为:key down -> key press -> key up

注意到键盘按下的event参数,该参数为KeyboardEvent事件对象,其中包含按键相关的一些属性。其中:

  • type: 事件类型,如\'keydown\'或者\'keyup\'
  • key: 表示按下的键盘内容是什么即键值,按下字母\'p\'时,值为\'p\'
  • code: 表示键盘代码,按下字母\'p\'时,值为\'KeyP\'
  • keyCode(过时): 整数,表示键码,每个键都有唯一的键码,字母\'p\'的键码为80
  • altKey: 布尔值,表示此时的alt键是否也按下
  • ctrKey: 布尔值,表示此时的alt键是否也按下
  • shiftKey: 布尔值,表示此时的shift键是否也按下
  • metaKey: 布尔值,windows平台表示Window键是否同时按下,mac表示Command键是否同时按下
  • repeat: 布尔值,如果一个键一直被按着,则其值为true,表示重复

可以通过检查这些属性来判断用户按下的是什么键,以及是否ctrl和alt等键是否同时按下。

document.onkeydown = function(event) {
    // 键盘按下是触发
	console.log(\'key down: \' + event.key);
	if (event.altKey) {
	    console.log(\'alt is active\');
    }
	if (event.shiftKey) {
	    console.log(\'shift is active\');
	}
};

监听鼠标事件

相应的也可以监听鼠标相关的事件,触发时的参数eventMouseEvent对象类型:

  • onclick: 鼠标点击事件
  • ondblclick: 鼠标双击事件
  • onmousedown: 鼠标上的按钮被按下了
  • onmouseup: 鼠标按下后松开时触发的事件
  • onmousemove: 鼠标移动时触发的事件
  • onmouseout: 鼠标离开监听该事件的元素或子元素时触发的事件
  • onmouseover: 鼠标移动到监听该事件的元素或子元素时触发的事件
  • onmousewheel: 鼠标滚轮事件,一般使用onscroll事件

MouseEvent对象中包含下面比较有用的属性:

  • type: 事件类型,如\'mosemove\'或者\'mousedown\'
  • button: 整型,触发鼠标事件时按下的按钮编号
  • buttons: 整型,触发鼠标事件时弹起来的按钮编号
  • clientX: 鼠标指针在DOM内容区的X坐标
  • clientY:鼠标指针在DOM内容区的Y坐标
  • offsetX: 鼠标指针相对父节点填充边缘的X坐标
  • offsetY: 鼠标指针相对父节点填充边缘的Y坐标
  • screenX: 鼠标指针在全局屏幕的X坐标
  • screenY: 鼠标指针在全局屏幕的Y坐标
  • pageX: 鼠标指针在整个DOM内容(包括分页)的X坐标
  • pageY: 鼠标指针在整个DOM内容(包括分页)的Y坐标
  • altKey: 布尔值,表示此时的alt键是否也按下
  • ctrKey: 布尔值,表示此时的alt键是否也按下
  • shiftKey: 布尔值,表示此时的shift键是否也按下
  • metaKey: 布尔值,windows平台表示Window键是否同时按下,mac表示Command键是否同时按下

通过鼠标事件的event属性,可以获取鼠标点击的位置,这里有对各种坐标的相关介绍,鼠标点击时是否按住ctrl等。

监听连续的按键事件实现秘笈开启

在很多游戏中,都有隐藏的秘笈,比如上上下下左左右右BABA这样的秘笈,那么怎么在网页监听事件,能够知道用户是按下了这个秘笈呢?(才不是要在隐藏什么奇怪的东西才用这个的>_<)演示地址(输入秘笈真的有惊喜!):http://asset.uusama.com/example/keycode.html

实现的方法就是用一个数组来记录连续按键的状态,每次按键正确则匹配下一个,直到所有匹配成功,看下面代码:

// 上上下下左左右右BABA的键值
const secretKey = [\'up\', \'up\', \'down\', \'down\', \'left\', \'left\', \'right\', \'right\', \'b\', \'a\', \'b\', \'a\'];
// 秘笈的键码
const secretKeyCode = [38, 38, 40, 40, 37, 37, 39, 39, 66, 65, 66, 65];
// 当前按键匹配的状态
let secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0);
// 当前正确秘笈按键的索引
// let correctCodeIndex = 0;
const CORRECT_STATUS = 1;  // 表示正确匹配按键的状态

document.onkeydown = function(event) {
    // 查找第一个0的位置,即当前按键应该匹配的位置
    let correctCodeIndex = secretKeyCodeStatus.lastIndexOf(CORRECT_STATUS);
    correctCodeIndex = correctCodeIndex === -1 ? 0 : correctCodeIndex + 1;

    // 如果所有的按键都正确,则返回
    if (correctCodeIndex > secretKeyCode.length) {
        alert(\'你成功打开了秘笈!通往哲♂学♂之路啊,我命令你开启吧!\');
        return true;
    }

    // 如果本次按键正确,则记录
    if (event.keyCode === secretKeyCode[correctCodeIndex]) {
        console.log(\'keyCode: \' + event.keyCode + \' code: \' + event.code + \'  --correct,index:\' + correctCodeIndex);
        // 所有按键都正确则成功
        if (correctCodeIndex + 1 === secretKeyCodeStatus.length) {
            alert(\'你成功打开了秘笈!通往哲♂学♂之路啊,我命令你开启吧!\');
            // 重置状态
            secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0);
            return true;
        } else {
            // 否则记录当前按键成功
            secretKeyCodeStatus[correctCodeIndex] = CORRECT_STATUS;
        }
    } else {
        console.log(\'keyCode: \' + event.keyCode + \' code: \' + event.code + \'  --reset\');
        // 按键错误则重置
        secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0);
    }
};

模拟键盘和鼠标事件

上面我们说明了如何监听页面的按键和键盘事件,但是有的时候我们需要使用代码模拟按钮操作。

比如看到很多图片的时候,我们需要批量下载,这个时候可以打开控制台,写一段JS代码批量模拟下载步骤即可,而不用一个一个的手动点击,非常方便。

模拟鼠标点击

最简单的就是模拟点击了,我们只需要选中一个元素,然后执行click函数即可。

下面的代码实现在一个表格中,点击每一个图片。

const images = document.getElementById(\'content\').getElementsByTagName(\'img\');
for (let image of images) {
	images.click();
}

如果要模拟鼠标双击,或者鼠标移动,则没有简单的函数可以调用。这个时候我们需要新建一个MouseEvent对象,并手动触发即可。

创建MouseEvent对象的语法为:const event = new MouseEvent(typeArg, mouseEventInit);

  • typeArg为鼠标事件类型,即上面的监听鼠标事件去掉on后的字符串,
    • click: 鼠标点击事件
    • dblclick: 鼠标双击事件
    • mousedown: 鼠标上的按钮被按下了
    • mouseup: 鼠标按下后松开时触发的事件
    • mousemove: 鼠标移动时触发的事件
    • mouseout: 鼠标离开监听该事件的元素或子元素时触发的事件
    • mouseover: 鼠标移动到监听该事件的元素或子元素时触发的事件
  • mouseEventInitMouseEvent初始化的选项,指定鼠标事件的各种属性,可选值如下:
    • button: 整型,触发鼠标事件时按下的按钮编号
    • buttons: 整型,触发鼠标事件时弹起来的按钮编号
    • clientX: 鼠标指针在DOM内容区的X坐标
    • clientY:鼠标指针在DOM内容区的Y坐标
    • offsetX: 鼠标指针相对父节点填充边缘的X坐标
    • offsetY: 鼠标指针相对父节点填充边缘的Y坐标
    • screenX: 鼠标指针在全局屏幕的X坐标
    • screenY: 鼠标指针在全局屏幕的Y坐标
    • pageX: 鼠标指针在整个DOM内容(包括分页)的X坐标
    • pageY: 鼠标指针在整个DOM内容(包括分页)的Y坐标
    • altKey: 布尔值,表示此时的alt键是否也按下
    • ctrKey: 布尔值,表示此时的alt键是否也按下
    • shiftKey: 布尔值,表示此时的shift键是否也按下
    • metaKey: 布尔值,windows平台表示Window键是否同时按下,mac表示Command键是否同时按下

比如下面的示例在坐标200,200处触发一个鼠标双击事件:

// 创建一个event对象
const createEvent = new MouseEvent(\'dblclick\', {
	clientX: 300,
	clientY: 300,
});

// 触发该事件
document.dispatchEvent(createEvent);

可以使用任意的Document对象的dispatchEvent方法触发一个事件,这些触发的事件和实际发生的事件一模一样。

模拟键盘输入事件

和模拟鼠标事件一样,不过这儿我们要创建一个KeyboardEvent事件对象。

创建KeyboardEvent对象的语法类似为:const event = new KeyboardEvent(typeArg, KeyboardEventInit);

  • typeArg为键盘输入事件类型,即上面的监听键盘输入事件去掉on后的字符串,
    • keydown: 键盘按下这个动作
    • keypress: 键盘被按住
    • keyup: 键盘被弹起
  • KeyboardEventInitKeyboardEvent初始化的选项,指定键盘输入事件的各种属性,可选值如下:
    • type: 事件类型,如\'keydown\'或者\'keyup\'
    • key: 表示按下的键盘内容是什么即键值,按下字母\'p\'时,值为\'p\'
    • code: 表示键盘代码,按下字母\'p\'时,值为\'KeyP\'
    • keyCode(过时): 整数,表示键码,每个键都有唯一的键码,字母\'p\'的键码为80
    • altKey: 布尔值,表示此时的alt键是否也按下
    • ctrKey: 布尔值,表示此时的alt键是否也按下
    • shiftKey: 布尔值,表示此时的shift键是否也按下
    • metaKey: 布尔值,windows平台表示Window键是否同时按下,mac表示Command键是否同时按下
    • repeat: 布尔值,如果一个键一直被按着,则其值为true,表示重复

比如实现在按下字母\'a\'键时,自动按下\'alt+ctrl+a\'可以像下面实现。

// 监听按键事件
document.onkeydown = function(event) {
	console.log(\'keyCode: \' + event.keyCode + \' code: \' + event.code + \' alt:\' + event.altKey);
	if (event.keyCode === 65 || event.code === \'KeyA\') {
		// 如果按下的是a键,则新建一个a键按下的事件并触发
		const createEvent = new KeyboardEvent(\'keydown\', {
			altKey: true,
			shiftKey: true,
			keyCode: 65,
			code: \'KeyA\'
		});
		document.dispatchEvent(createEvent);
	}
};

然后你就会发现上面的函数疯狂的输出A键被按下,哈哈哈!知道内存达到限制!

附录

最后附上键值和键码的对应关系对象,可以直接拷贝使用:

const keyCodes = {
	0: \'That key has no keycode\',
	3: \'break\',
	8: \'backspace / delete\',
	9: \'tab\',
	12: \'clear\',
	13: \'enter\',
	16: \'shift\',
	17: \'ctrl\',
	18: \'alt\',
	19: \'pause/break\',
	20: \'caps lock\',
	21: \'hangul\',
	25: \'hanja\',
	27: \'escape\',
	28: \'conversion\',
	29: \'non-conversion\',
	32: \'spacebar\',
	33: \'page up\',
	34: \'page down\',
	35: \'end\',
	36: \'home\',
	37: \'left arrow\',
	38: \'up arrow\',
	39: \'right arrow\',
	40: \'down arrow\',
	41: \'select\',
	42: \'print\',
	43: \'execute\',
	44: \'Print Screen\',
	45: \'insert\',
	46: \'delete\',
	47: \'help\',
	48: \'0\',
	49: \'1\',
	50: \'2\',
	51: \'3\',
	52: \'4\',
	53: \'5\',
	54: \'6\',
	55: \'7\',
	56: \'8\',
	57: \'9\',
	58: \':\',
	59: \'semicolon (firefox), equals\',
	60: \'<\',
	61: \'equals (firefox)\',
	63: \'ß\',
	64: \'@ (firefox)\',
	65: \'a\',
	66: \'b\',
	67: \'c\',
	68: \'d\',
	69: \'e\',
	70: \'f\',
	71: \'g\',
	72: \'h\',
	73: \'i\',
	74: \'j\',
	75: \'k\',
	76: \'l\',
	77: \'m\',
	78: \'n\',
	79: \'o\',
	80: \'p\',
	81: \'q\',
	82: \'r\',
	83: \'s\',
	84: \'t\',
	85: \'u\',
	86: \'v\',
	87: \'w\',
	88: \'x\',
	89: \'y\',
	90: \'z\',
	91: \'Windows Key / Left ⌘ / Chromebook Search key\',
	92: \'right window key\',
	93: \'Windows Menu / Right ⌘\',
	95: \'sleep\',
	96: \'numpad 0\',
	97: \'numpad 1\',
	98: \'numpad 2\',
	99: \'numpad 3\',
	100: \'numpad 4\',
	101: \'numpad 5\',
	102: \'numpad 6\',
	103: \'numpad 7\',
	104: \'numpad 8\',
	105: \'numpad 9\',
	106: \'multiply\',
	107: \'add\',
	108: \'numpad period (firefox)\',
	109: \'subtract\',
	110: \'decimal point\',
	111: \'divide\',
	112: \'f1\',
	113: \'f2\',
	114: \'f3\',
	115: \'f4\',
	116: \'f5\',
	117: \'f6\',
	118: \'f7\',
	119: \'f8\',
	120: \'f9\',
	121: \'f10\',
	122: \'f11\',
	123: \'f12\',
	124: \'f13\',
	125: \'f14\',
	126: \'f15\',
	127: \'f16\',
	128: \'f17\',
	129: \'f18\',
	130: \'f19\',
	131: \'f20\',
	132: \'f21\',
	133: \'f22\',
	134: \'f23\',
	135: \'f24\',
	144: \'num lock\',
	145: \'scroll lock\',
	160: \'^\',
	161: \'!\',
	162: \'؛ (arabic semicolon)\',
	163: \'#\',
	164: \'$\',
	165: \'ù\',
	166: \'page backward\',
	167: \'page forward\',
	168: \'refresh\',
	169: \'closing paren (AZERTY)\',
	170: \'*\',
	171: \'~ + * key\',
	172: \'home key\',
	173: \'minus (firefox), mute/unmute\',
	174: \'decrease volume level\',
	175: \'increase volume level\',
	176: \'next\',
	177: \'previous\',
	178: \'stop\',
	179: \'play/pause\',
	180: \'e-mail\',
	181: \'mute/unmute (firefox)\',
	182: \'decrease volume level (firefox)\',
	183: \'increase volume level (firefox)\',
	186: \'semi-colon / ñ\',
	187: \'equal sign\',
	188: \'comma\',
	189: \'dash\',
	190: \'period\',
	191: \'forward slash / ç\',
	192: \'grave accent / ñ / æ / ö\',
	193: \'?, / or °\',
	194: \'numpad period (chrome)\',
	219: \'open bracket\',
	220: \'back slash\',
	221: \'close bracket / å\',
	222: \'single quote / ø / ä\',
	223: \'`\',
	224: \'left or right ⌘ key (firefox)\',
	225: \'altgr\',
	226: \'< /git >, left back slash\',
	230: \'GNOME Compose Key\',
	231: \'ç\',
	233: \'XF86Forward\',
	234: \'XF86Back\',
	235: \'non-conversion\',
	240: \'alphanumeric\',
	242: \'hiragana/katakana\',
	243: \'half-width/full-width\',
	244: \'kanji\',
	251: "unlock trackpad (Chrome/Edge)",
	255: \'toggle touchpad\',
};

// 压缩之后的
const keyCodesMin={0:"That key has no keycode",3:"break",8:"backspace / delete",9:"tab",12:"clear",13:"enter",16:"shift",17:"ctrl",18:"alt",19:"pause/break",20:"caps lock",21:"hangul",25:"hanja",27:"escape",28:"conversion",29:"non-conversion",32:"spacebar",33:"page up",34:"page down",35:"end",36:"home",37:"left arrow",38:"up arrow",39:"right arrow",40:"down arrow",41:"select",42:"print",43:"execute",44:"Print Screen",45:"insert",46:"delete",47:"help",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",58:":",59:"semicolon (firefox), equals",60:"<",61:"equals (firefox)",63:"ß",64:"@ (firefox)",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",91:"Windows Key / Left ⌘ / Chromebook Search key",92:"right window key",93:"Windows Menu / Right ⌘",95:"sleep",96:"numpad 0",97:"numpad 1",98:"numpad 2",99:"numpad 3",100:"numpad 4",101:"numpad 5",102:"numpad 6",103:"numpad 7",104:"numpad 8",105:"numpad 9",106:"multiply",107:"add",108:"numpad period (firefox)",109:"subtract",110:"decimal point",111:"divide",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",124:"f13",125:"f14",126:"f15",127:"f16",128:"f17",129:"f18",130:"f19",131:"f20",132:"f21",133:"f22",134:"f23",135:"f24",144:"num lock",145:"scroll lock",160:"^",161:"!",162:"؛ (arabic semicolon)",163:"#",164:"$",165:"ù",166:"page backward",167:"page forward",168:"refresh",169:"closing paren (AZERTY)",170:"*",171:"~ + * key",172:"home key",173:"minus (firefox), mute/unmute",174:"decrease volume level",175:"increase volume level",176:"next",177:"previous",178:"stop",179:"play/pause",180:"e-mail",181:"mute/unmute (firefox)",182:"decrease volume level (firefox)",183:"increase volume level (firefox)",186:"semi-colon / ñ",187:"equal sign",188:"comma",189:"dash",190:"period",191:"forward slash / ç",192:"grave accent / ñ / æ / ö",193:"?, / or °",194:"numpad period (chrome)",219:"open bracket",220:"back slash",221:"close bracket / å",222:"single quote / ø / ä",223:"`",224:"left or right ⌘ key (firefox)",225:"altgr",226:"< /git >, left back slash",230:"GNOME Compose Key",231:"ç",233:"XF86Forward",234:"XF86Back",235:"non-conversion",240:"alphanumeric",242:"hiragana/katakana",243:"half-width/full-width",244:"kanji",251:"unlock trackpad (Chrome/Edge)",255:"toggle touchpad",};

分类:

技术点:

相关文章: