键盘事件
键盘事件用来描述键盘行为,主要有keydown、keypress、keyup三个事件。
-
keydown:按下键盘时触发该事件。
-
keypress:只要按下的键并非Ctrl、Alt、Shift和Meta,就接着触发keypress事件。
-
keyup:松开键盘时触发该事件。
下面是一个例子,对文本框设置keypress监听函数,只允许输入数字。
// HTML代码为
// <input type="text"
// name="myInput"
// onkeypress="return numbersOnly(this, event);"
// onpaste="return false;"
// />
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,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请求的过程、<img>、<audio>、<video>、<style>、<link>加载外部资源的过程。下载和上传都会发生进度事件。
进度事件有以下几种。
-
abort事件:当进度事件被中止时触发。如果发生错误,导致进程中止,不会触发该事件。
-
error事件:由于错误导致资源无法加载时触发。
-
load事件:进度成功结束时触发。
-
loadstart事件:进度开始时触发。
-
loadend事件:进度停止时触发,发生顺序排在error事件\abort事件\load事件后面。
-
progress事件:当操作处于进度之中,由传输的数据块不断触发。
-
timeout事件:进度超过限时触发。
image.addEventListener('load', function(event) {
image.classList.add('finished');
});
image.addEventListener(‘error’, function(event) {
image.style.display = ‘none’;
});
上面代码在图片元素加载完成后,为图片元素的class属性添加一个值“finished”。如果加载失败,就把图片元素的样式设置为不显示。
有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能使得load和error事件的监听函数根本不会被执行。所以,比较可靠的方式,是用complete属性先判断一下是否加载完成。
function loaded() {
// code after image loaded
}
if (image.complete) {
loaded();
} else {
image.addEventListener(‘load’, loaded);
}
由于DOM没有提供像complete属性那样的,判断是否发生加载错误的属性,所以error事件的监听函数最好放在img元素的HTML属性中,这样才能保证发生加载错误时百分之百会执行。
<img src="/wrong/url" "this.style.display='none';" />
error事件有一个特殊的性质,就是不会冒泡。这样的设计是正确的,防止引发父元素的error事件监听函数。
进度事件使用ProgressEvent对象表示。ProgressEvent实例有以下属性。
-
lengthComputable:返回一个布尔值,表示当前进度是否具有可计算的长度。如果为false,就表示当前进度无法测量。
-
total:返回一个数值,表示当前进度的总长度。如果是通过HTTP下载某个资源,表示内容本身的长度,不含HTTP头部的长度。如果lengthComputable属性为false,则total属性就无法取得正确的值。
-
loaded:返回一个数值,表示当前进度已经完成的数量。该属性除以total属性,就可以得到目前进度的百分比。
下面是一个例子。
var xhr = new XMLHttpRequest();
xhr.addEventListener(“progress”, updateProgress, false);
xhr.addEventListener(“load”, transferComplete, false);
xhr.addEventListener(“error”, transferFailed, false);
xhr.addEventListener(“abort”, transferCanceled, false);
xhr.open();
function updateProgress (e) {
if (e.lengthComputable) {
var percentComplete = e.loaded / e.total;
} else {
console.log(‘不能计算进度’);
}
}
function transferComplete(e) {
console.log(‘传输结束’);
}
function transferFailed(evt) {
console.log(‘传输过程中发生错误’);
}
function transferCanceled(evt) {
console.log(‘用户取消了传输’);
}
loadend事件的监听函数,可以用来取代abort事件/load事件/error事件的监听函数。
req.addEventListener("loadend", loadEnd, false);
function loadEnd(e) {
console.log(‘传输结束,成功失败未知’);
}
loadend事件本身不提供关于进度结束的原因,但可以用它来做所有进度结束场景都需要做的一些操作。
另外,上面是下载过程的进度事件,还存在上传过程的进度事件。这时所有监听函数都要放在XMLHttpRequest.upload对象上面。
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener(“progress”, updateProgress, false);
xhr.upload.addEventListener(“load”, transferComplete, false);
xhr.upload.addEventListener(“error”, transferFailed, false);
xhr.upload.addEventListener(“abort”, transferCanceled, false);
xhr.open();
浏览器提供一个ProgressEvent构造函数,用来生成进度事件的实例。
progressEvent = new ProgressEvent(type, {
lengthComputable: aBooleanValue,
loaded: aNumber,
total: aNumber
});
上面代码中,ProgressEvent构造函数的第一个参数是事件类型(字符串),第二个参数是配置对象,用来指定lengthComputable属性(默认值为false)、loaded属性(默认值为0)、total属性(默认值为0)。