zoukankan      html  css  js  c++  java
  • JavaScript键盘鼠标事件处理

    监听键盘鼠标事件

    监听某个按键事件

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

    • 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",};
    
  • 相关阅读:
    Docker中查看Mysql数据库中的各环境参数
    Hbase shell 输入无法使用退格键删除解决办法
    HBase启动时报错:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1.8.0_152/bin/java
    SSH无密码验证
    详解分布式应用程序协调服务Zookeeper
    zookeeper的原理及使用
    Hadoop、Yarn和vcpu资源的配置
    一文让您全面了解清楚HBase数据库的所有知识点,值得收藏!
    基于Docker一键部署大规模Hadoop集群及设计思路
    PHP ServerPush (推送) 技术的探讨【转】
  • 原文地址:https://www.cnblogs.com/youyoui/p/10381457.html
Copyright © 2011-2022 走看看