本节介绍各种常见的浏览器事件。
鼠标事件
鼠标事件指与鼠标相关的事件,主要有以下一些。
click 事件,dblclick 事件
当用户在Element节点、document
节点、window
对象上单击鼠标(或者按下回车键)时,click
事件触发。
“鼠标单击”定义为,用户在同一个位置完成一次mousedown
动作和mouseup
动作。它们的触发顺序是:mousedown
首先触发,mouseup
接着触发,click
最后触发。
下面是一个设置click
事件监听函数的例子。
div.addEventListener("click", function( event ) {
// 显示在该节点,鼠标连续点击的次数
event.target.innerHTML = "click count: " + event.detail;
}, false);
下面的代码是利用click
事件进行CSRF攻击(Cross-site request forgery)的一个例子。
伪装的链接
dblclick
事件当用户在element
、document
、window
对象上,双击鼠标时触发。该事件会在mousedown
、mouseup
、click
之后触发。
mouseup 事件,mousedown 事件,mousemove 事件
mouseup
事件在释放按下的鼠标键时触发。
mousedown
事件在按下鼠标键时触发。
mousemove
事件当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次代码。
mouseover 事件,mouseenter 事件
mouseover
事件和mouseenter
事件,都是鼠标进入一个节点时触发。
两者的区别是,mouseenter
事件只触发一次,而只要鼠标在节点内部移动,mouseover
事件会在子节点上触发多次。
// HTML代码为
//
// - item 1
// - item 2
// - item 3
//
var test = document.getElementById('test');
// 进入test节点以后,该事件只会触发一次
// event.target 是 ul 节点
test.addEventListener('mouseenter', function (event) {
event.target.style.color = 'purple';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
// 进入test节点以后,只要在子Element节点上移动,该事件会触发多次
// event.target 是 li 节点
test.addEventListener('mouseover', function (event) {
event.target.style.color = 'orange';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
mouseout 事件,mouseleave 事件
mouseout
事件和mouseleave
事件,都是鼠标离开一个节点时触发。
两者的区别是,mouseout
事件会冒泡,mouseleave
事件不会。子节点的mouseout
事件会冒泡到父节点,进而触发父节点的mouseout
事件。mouseleave
事件就没有这种效果,所以离开子节点时,不会触发父节点的监听函数。
contextmenu 事件
contextmenu
事件在一个节点上点击鼠标右键时触发,或者按下“上下文菜单”键时触发。
MouseEvent 对象
概述
鼠标事件使用MouseEvent
对象表示,它继承UIEvent
对象和Event
对象。浏览器提供一个MouseEvent
构造函数,用于新建一个MouseEvent
实例。
event = new MouseEvent(typeArg, mouseEventInit);
MouseEvent
构造函数的第一个参数是事件名称(可能的值包括click
、mousedown
、mouseup
、mouseover
、mousemove
、mouseout
),第二个参数是一个事件初始化对象。该对象可以配置以下属性。
- screenX,设置鼠标相对于屏幕的水平坐标(但不会移动鼠标),默认为0,等同于MouseEvent.screenX属性。
- screenY,设置鼠标相对于屏幕的垂直坐标,默认为0,等同于MouseEvent.screenY属性。
- clientX,设置鼠标相对于窗口的水平坐标,默认为0,等同于MouseEvent.clientX属性。
- clientY,设置鼠标相对于窗口的垂直坐标,默认为0,等同于MouseEvent.clientY属性。
- ctrlKey,设置是否按下ctrl键,默认为false,等同于MouseEvent.ctrlKey属性。
- shiftKey,设置是否按下shift键,默认为false,等同于MouseEvent.shiftKey属性。
- altKey,设置是否按下alt键,默认为false,等同于MouseEvent.altKey属性。
- metaKey,设置是否按下meta键,默认为false,等同于MouseEvent.metaKey属性。
- button,设置按下了哪一个鼠标按键,默认为0。-1表示没有按键,0表示按下主键(通常是左键),1表示按下辅助键(通常是中间的键),2表示按下次要键(通常是右键)。
- buttons,设置按下了鼠标哪些键,是一个3个比特位的二进制值,默认为0。1表示按下主键(通常是左键),2表示按下次要键(通常是右键),4表示按下辅助键(通常是中间的键)。
- relatedTarget,设置一个Element节点,在mouseenter和mouseover事件时,表示鼠标刚刚离开的那个Element节点,在mouseout和mouseleave事件时,表示鼠标正在进入的那个Element节点。默认为null,等同于MouseEvent.relatedTarget属性。
以下属性也是可配置的,都继承自UIEvent构造函数和Event构造函数。
- bubbles,布尔值,设置事件是否冒泡,默认为false,等同于Event.bubbles属性。
- cancelable,布尔值,设置事件是否可取消,默认为false,等同于Event.cancelable属性。
- view,设置事件的视图,一般是window或document.defaultView,等同于Event.view属性。
- detail,设置鼠标点击的次数,等同于Event.detail属性。
下面是一个例子。
function simulateClick() {
var event = new MouseEvent('click', {
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('checkbox');
cb.dispatchEvent(event);
}
上面代码生成一个鼠标点击事件,并触发该事件。
以下介绍MouseEvent实例的属性。
altKey,ctrlKey,metaKey,shiftKey
以下属性返回一个布尔值,表示鼠标事件发生时,是否按下某个键。
-
altKey
属性:Alt 键 -
ctrlKey
属性:Ctrl 键 -
metaKey
属性:Meta 键(Mac键盘是一个四瓣的小花,Windows键盘是Windows键) -
shiftKey
属性:Shift 键
// HTML代码为
//
function showKey(e){
console.log("ALT key pressed: " + e.altKey);
console.log("CTRL key pressed: " + e.ctrlKey);
console.log("META key pressed: " + e.metaKey);
console.log("SHIFT key pressed: " + e.shiftKey);
}
上面代码中,点击网页会输出是否同时按下Alt键。
button,buttons
以下属性返回事件的鼠标键信息。
(1)button
button属性返回一个数值,表示按下了鼠标哪个键。
- -1:没有按下键。
- 0:按下主键(通常是左键)。
- 1:按下辅助键(通常是中键或者滚轮键)。
- 2:按下次键(通常是右键)。
// HTML代码为
//
var whichButton = function (e) {
switch (e.button) {
case 0:
console.log('Left button clicked.');
break;
case 1:
console.log('Middle button clicked.');
break;
case 2:
console.log('Right button clicked.');
break;
default:
console.log('Unexpected code: ' + e.button);
}
}
(2)buttons
buttons属性返回一个3个比特位的值,表示同时按下了哪些键。它用来处理同时按下多个鼠标键的情况。
- 1:二进制为001,表示按下左键。
- 2:二进制为010,表示按下右键。
- 4:二进制为100,表示按下中键或滚轮键。
同时按下多个键的时候,每个按下的键对应的比特位都会有值。比如,同时按下左键和右键,会返回3(二进制为011)。
clientX,clientY,movementX,movementY,screenX,screenY
以下属性与事件的位置相关。
(1)clientX,clientY
clientX属性返回鼠标位置相对于浏览器窗口左上角的水平坐标,单位为像素,与页面是否横向滚动无关。
clientY属性返回鼠标位置相对于浏览器窗口左上角的垂直坐标,单位为像素,与页面是否纵向滚动无关。
// HTML代码为
//
function showCoords(evt){
console.log(
"clientX value: " + evt.clientX + "\n" +
"clientY value: " + evt.clientY + "\n"
);
}
(2)movementX,movementY
movementX属性返回一个水平位移,单位为像素,表示当前位置与上一个mousemove事件之间的水平距离。在数值上,等于currentEvent.movementX = currentEvent.screenX - previousEvent.screenX。
movementY属性返回一个垂直位移,单位为像素,表示当前位置与上一个mousemove事件之间的垂直距离。在数值上,等于currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。
(3)screenX,screenY
screenX属性返回鼠标位置相对于屏幕左上角的水平坐标,单位为像素。
screenY属性返回鼠标位置相对于屏幕左上角的垂直坐标,单位为像素。
// HTML代码为
//
function showCoords(evt){
console.log(
"screenX value: " + evt.screenX + "\n"
+ "screenY value: " + evt.screenY + "\n"
);
}
relatedTarget
relatedTarget属性返回事件的次要相关节点。对于那些没有次要相关节点的事件,该属性返回null。
下表列出不同事件的target属性和relatedTarget属性含义。
事件名称 | target属性 | relatedTarget属性 |
---|---|---|
focusin | 接受焦点的节点 | 丧失焦点的节点 |
focusout | 丧失焦点的节点 | 接受焦点的节点 |
mouseenter | 将要进入的节点 | 将要离开的节点 |
mouseleave | 将要离开的节点 | 将要进入的节点 |
mouseout | 将要离开的节点 | 将要进入的节点 |
mouseover | 将要进入的节点 | 将要离开的节点 |
dragenter | 将要进入的节点 | 将要离开的节点 |
dragexit | 将要离开的节点 | 将要进入的节点 |
下面是一个例子。
// HTML代码为
//
//
//
var inner = document.getElementById("inner");
inner.addEventListener("mouseover", function (){
console.log('进入' + event.target.id + " 离开" + event.relatedTarget.id);
});
inner.addEventListener("mouseenter", function (){
console.log('进入' + event.target.id + " 离开" + event.relatedTarget.id);
});
inner.addEventListener("mouseout", function (){
console.log('离开' + event.target.id + " 进入" + event.relatedTarget.id);
});
inner.addEventListener("mouseleave", function (){
console.log('离开' + event.target.id + " 进入" + event.relatedTarget.id);
});
// 鼠标从outer进入inner,输出
// 进入inner 离开outer
// 进入inner 离开outer
// 鼠标从inner进入outer,输出
// 离开inner 进入outer
// 离开inner 进入outer
wheel事件
wheel
事件是与鼠标滚轮相关的事件,目前只有一个wheel
事件。用户滚动鼠标的滚轮,就触发这个事件。
该事件除了继承了MouseEvent、UIEvent、Event的属性,还有几个自己的属性。
- deltaX:返回一个数值,表示滚轮的水平滚动量。
- deltaY:返回一个数值,表示滚轮的垂直滚动量。
- deltaZ:返回一个数值,表示滚轮的Z轴滚动量。
- deltaMode:返回一个数值,表示滚动的单位,适用于上面三个属性。0表示像素,1表示行,2表示页。
浏览器提供一个WheelEvent构造函数,可以用来生成滚轮事件的实例。它接受两个参数,第一个是事件名称,第二个是配置对象。
var syntheticEvent = new WheelEvent("syntheticWheel", {"deltaX": 4, "deltaMode": 0});
键盘事件
键盘事件用来描述键盘行为,主要有keydown、keypress、keyup三个事件。
keydown:按下键盘时触发该事件。
keypress:只要按下的键并非Ctrl、Alt、Shift和Meta,就接着触发keypress事件。
keyup:松开键盘时触发该事件。
下面是一个例子,对文本框设置keypress监听函数,只允许输入数字。
// HTML代码为
//
function numbersOnly(oToCheckField, oKeyEvent) {
return oKeyEvent.charCode === 0
|| /\d/.test(String.fromCharCode(oKeyEvent.charCode));
}
如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下。
- keydown
- keypress
- keydown
- keypress
- (重复以上过程)
- keyup
键盘事件使用KeyboardEvent对象表示,该对象继承了UIEvent和MouseEvent对象。浏览器提供KeyboardEvent构造函数,用来新建键盘事件的实例。
event = new KeyboardEvent(typeArg, KeyboardEventInit);
KeyboardEvent构造函数的第一个参数是一个字符串,表示事件类型,第二个参数是一个事件配置对象,可配置以下字段。
- key,对应KeyboardEvent.key属性,默认为空字符串。
- ctrlKey,对应KeyboardEvent.ctrlKey属性,默认为false。
- shiftKey,对应KeyboardEvent.shiftKey属性,默认为false。
- altKey,对应KeyboardEvent.altKey属性,默认为false。
- metaKey,对应KeyboardEvent.metaKey属性,默认为false。
下面就是KeyboardEvent实例的属性介绍。
altKey,ctrlKey,metaKey,shiftKey
以下属性返回一个布尔值,表示是否按下对应的键。
- altKey:alt键
- ctrlKey:ctrl键
- metaKey:meta键(mac系统是一个四瓣的小花,windows系统是windows键)
- shiftKey:shift键
function showChar(e){
console.log("ALT: " + e.altKey);
console.log("CTRL: " + e.ctrlKey);
console.log("Meta: " + e.metaKey);
console.log("Meta: " + e.shiftKey);
}
key,charCode
key属性返回一个字符串,表示按下的键名。如果同时按下一个控制键和一个符号键,则返回符号键的键名。比如,按下Ctrl+a,则返回a。如果无法识别键名,则返回字符串Unidentified。
主要功能键的键名(不同的浏览器可能有差异):Backspace,Tab,Enter,Shift,Control,Alt,CapsLock,Esc,Spacebar,PageUp,PageDown,End,Home,Left,Right,Up,Down,PrintScreen,Insert,Del,Win,F1~F12,NumLock,Scroll等。
charCode属性返回一个数值,表示keypress事件按键的Unicode值,keydown和keyup事件不提供这个属性。注意,该属性已经从标准移除,虽然浏览器还支持,但应该尽量不使用。
进度事件
进度事件用来描述一个事件进展的过程,比如XMLHttpRequest对象发出的HTTP请求的过程、、