JavaScript 复习之各类事件(一)

504 阅读5分钟

鼠标事件

一、事件的种类

  • clickdblclickmousedownmouseupmousemove
  • mouseenter:鼠标进入一个节点时触发,进入子节点不会触发
  • mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发
  • mouseout:鼠标离开一个节点时触发,离开父节点也会触发
  • mouseleave:鼠标离开一个节点触发,离开父节点不会触发
  • contextmenu:鼠标右键时触发,或者按下“上下文菜单键”时触发
  • wheel:滚动鼠标的滚动轮时触发

二、MounseEvent 接口的实例属性

MouseEvent.altKeyMouseEvent.ctrlKeyMouseEvent.metaKeyMouseEvent.shiftKey这四个属性都返回一个布尔值,表示事件发生时,是否按下对应的键。它们都是只读属性。

  • altKey属性:Alt 键
  • ctrlKey属性:Ctrl 键
  • metaKey属性:Meta 键(Mac 键盘是一个四瓣的小花,Windows 键盘是 Windows 键)
  • shiftKey属性:Shift 键

MouseEvent.button返回一个数值,表示事件发生时按下了鼠标的哪个键,属性只读。

  • 0:按下主键(通常是左键),或者该事件没有初始化这个属性(比如mousemove事件)。
  • 1:按下辅助键(通常是中键或者滚轮键)。
  • 2:按下次键(通常是右键)。

MouseEvent.buttons属性返回一个三个比特位的值,表示同时按下了哪些键。它用来处理同时按下多个鼠标键的情况。该属性只读。

  • 1:二进制为001(十进制的1),表示按下左键。

  • 2:二进制为010(十进制的2),表示按下右键。

  • 4:二进制为100(十进制的4),表示按下中键或滚轮键。

MouseEvent.clientX返回鼠标位置相对于浏览器窗口左上角的水平坐标(单位像素),MouseEvent.clientY返回垂直坐标。

MouseEvent.movementX返回当前位置与上一个mousemove事件之间的水平距离(单位像素)。MouseEvent.movementY属性返回当前位置与上一个mousemove事件之间的垂直距离(单位像素)。

currentEvent.movementX = currentEvent.screenX - previousEvent.screenX

currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。

MouseEvent.screenXMouseEvent.screenY返回鼠标位置相对于屏幕左上角的水平坐标和垂直坐标,属性只读

MouseEvent.offsetX,返回鼠标位置与目标节点左侧的padding边缘的水平距离。MouseEvent.offsetY返回与目标节点上方的padding边缘的垂直距离。

MouseEvent.pageX返回鼠标位置与文档左侧边缘的距离(单位像素),MouseEvent.pageY返回与文档上侧边缘的距离(单位像素)

MouseEvent.relatedTarget返回事件的相关节点。

事件名称 target 属性 relatedTarget 属性
focusin 接受焦点的节点 丧失焦点的节点
focusout 丧失焦点的节点 接受焦点的节点
mouseenter 将要进入的节点 将要离开的节点
mouseleave 将要离开的节点 将要进入的节点
mouseout 将要离开的节点 将要进入的节点
mouseover 将要进入的节点 将要离开的节点
dragenter 将要进入的节点 将要离开的节点
dragexit 将要离开的节点 将要进入的节点

键盘事件

一、事件种类

主要有:keydownkeypresskeyup

进度事件

一、事件的种类

用来描述资源加载的进度,主要是 AJAX 请求、<img><audio><video><style><link>等外部资源的加载触发。主要包含以下几种事件:

  • abort外部资源中止加载时(如用户取消)触发。发生错误导致不触发
  • error由于错误导致外部资源无法加载时触发
  • load外部资源加载成功时触发
  • loadstart外部资源开始加载时触发
  • loadend外部资源停止加载时触发,发生顺序在errorabortload等事件的后面
  • progress外部资源加载过程中不断触发
  • timeout加载超时时触发

注意,除了资源下载,文件上传也存在这些事件。

有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能loaderror事件的监听函数根本不会执行。所以,比较可靠的方式,是用complete属性先判断一下是否加载完成。

function loaded(){
    //...
}

if(image.complete){
    loaded();
}else{
    image.addEventListener('load',loaded);
}

由于 DOM 的元素节点没有提供是否加载错误的属性,所以error事件的监听函数最好放在<img>元素的 HTML 代码中,这样才能保证发生加载错误时百分之百会执行。

<img src="/wrong/url" onerror="this.style.display='none';" />

loadend事件的监听函数,可以用来取代abort事件、load事件、error事件的监听函数,应为他总是在这些事件之后发生

req.addEventListener('loadend',loadEnd,false);
function loadEnd(e){
    console.log('传输结束,成功失败未知');
}

error事件有一个特殊的性质,就是不会冒泡。所以,子元素的error事件,不会触发父元素的error事件监听函数。

二、ProgressEvent接口

用来描述外部资源加载的进度。浏览器提供ProgressEvent()构造函数,用来生成事件实例。

new ProgressEvent(type,options)

ProgressEvent()构造函数接受两个参数。第一个参数是字符串,表示事件的类型,这个参数是必须的。第二个参数是一个配置对象,表示事件的属性,该参数可选。配置对象除了可以使用Event接口的配置属性,还可以使用下面的属性,所有这些属性都是可选的。

  • lengthComputable:布尔值,表示加载的总量是否可以计算,默认是false

  • loaded:整数,表示已经加载的量,默认是0

  • total:整数,表示需要加载的总量,默认是0

ProgressEvent具有对应的实例属性。

  • ProgressEvent.lengthComputable
  • ProgressEvent.loaded
  • ProgressEvent.totalProgressEvent.lengthComputablefalse,他就没有意义。
var p = new ProgressEvent('load',{
    lengthComputable: true,
    loaded: 30,
    total: 100,
});

document.body.addEventListener('load',function(e){
    console.log('已经加载:'+(e.loaded/e.total)*100+'%');
});
document.body.dispathEvent(p);
// 已经加载:30%

上面代码先构造一个load事件,抛出后被监听函数捕捉到。

下面是一个实际的例子

var xhr = new XMLHttpRequest();
xhr.addEventListener('progress',updateProgress,false);
xhr.addEventListener('load',transferComplete,false);
xhr.addEventListener('error',transferFailed,false);
xhr.addEventListener('abort',transferVanceled,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('用户取消了传输');
}

上面是下载过程的进度事件,还存在上传过程的进度事件。这时所有监听函数都要放在XMLHttpRequest.upload对象上面。