用户交互是基于用户事件的,这些事件通常是鼠标事件、触摸事件以及键盘事件。

一. 监听器与事件处理程序

添加事件监听可以使用addEventListener()

element.addEventListener(type, handler [, userCapture])

移除事件监听可以使用removeEventListener()

element.removeEventListener(type, handler [, userCapture])

addEventListener()兼容IE9+浏览器和其他主流的现代浏览器,不兼容IE8及其以下版本。在IE8及其以下版本浏览器应使用attachEvent()来进行事件绑定。具体可查看:JavaScript事件处理兼容性总结

1.1 event事件类型

event事件类型具体可参考:http://www.w3school.com.cn/tags/html_ref_eventattributes.asp

1.2 event事件属性和方法

属性 描述 IE 非IE W3C
altKey 返回当事件被触发时,”ALT” 是否被按下。 Yes Yes Yes
button 返回当事件被触发时,哪个鼠标按钮被点击。 Yes Yes Yes
clientX 返回当事件被触发时,鼠标指针的水平坐标。 Yes Yes Yes
clientY 返回当事件被触发时,鼠标指针的垂直坐标。 Yes Yes Yes
ctrlKey 返回当事件被触发时,”CTRL” 键是否被按下。 Yes Yes Yes
metaKey 返回当事件被触发时,”meta” 键是否被按下。 No Yes Yes
relatedTarget 返回与事件的目标节点相关的节点。 No Yes Yes
screenX 返回当某个事件被触发时,鼠标指针的水平坐标。 Yes Yes Yes
screenY 返回当某个事件被触发时,鼠标指针的垂直坐标。 Yes Yes Yes
shiftKey 返回当事件被触发时,”SHIFT” 键是否被按下。 Yes Yes Yes
bubbles 返回布尔值,指示事件是否是起泡事件类型。 No Yes Yes
cancelable 返回布尔值,指示事件是否可拥可取消的默认动作。 No Yes Yes
currentTarget 返回其事件监听器触发该事件的元素。 No Yes Yes
eventPhase 返回事件传播的当前阶段。 Yes
target 返回触发此事件的元素(事件的目标节点)。 No Yes Yes
timeStamp 返回事件生成的日期和时间。 No Yes Yes
type 返回当前 Event 对象表示的事件的名称。 Yes Yes Yes
which 键盘码。 No Yes Yes
charCode 键盘码。 No Yes Yes
方法 描述 IE 非IE W3C
initEvent() 初始化新创建的 Event 对象的属性。 No Yes Yes
preventDefault() 通知浏览器不要执行与事件关联的默认动作。 No Yes Yes
stopPropagation() 不再派发事件。 No Yes Yes

除了上面W3C规范所规定的属性和方法外,IE浏览器还支持以下属性。

event对象的属性(IE特有):

属性 描述
cancelBubble 如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。
fromElement 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。
keyCode 对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
offsetX, offsetY 发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
returnValue 如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 fasle,可以取消发生事件的源元素的默认动作。
srcElement 对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
toElement 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
x, y 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。

二. 鼠标事件

鼠标事件常用的有:

  • mousedown
  • mouseup
  • click
  • dbclick
  • mousewheel
  • mousemove
  • mouseover
  • mouseout
  • mouseenter

三. 鼠标位置

每个鼠标事件都有两个属性用于确定鼠标的当前位置:pageX与pageY。结合这两个属性及目标元素相对于document的偏移量,可以确定鼠标在canvas元素上的相对坐标。遗憾的是,并不是所有的浏览器都支持pageX和pageY属性,可能要用到clientX和clientY。

获取鼠标位置的兼容性写法如下:

// 获取鼠标的当前位置
function getMouse(event) {
    var event = event || window.event;
    var mouse = {};
    var x, y;
    if(event.pageX || event.pageY) {
        x = event.pageX;
        y = event.pageY;
    } else if(event.clientX || event.clientY) {
        var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        x = event.clientX + scrollLeft;
        y = event.clientY + scrollTop;
    }
    mouse.x = x;
    mouse.y = y;
    return mouse;
}

使用方法如下:

<canvas id="canvas" width="300" height="300" style="background: #ccc;"></canvas>

var canvas = document.getElementById("canvas");
canvas.addEventListener("mousemove", function(e) {
    var x = getMouse(e).x,
        y = getMouse(e).y;
    console.log("x: " + x + "; y: " + y);
});

// 获取鼠标的当前位置
function getMouse(event) {
    var event = event || window.event;
    var mouse = {};
    var x, y;
    if(event.pageX || event.pageY) {
        x = event.pageX;
        y = event.pageY;
    } else if(event.clientX || event.clientY) {
        var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        x = event.clientX + scrollLeft;
        y = event.clientY + scrollTop;
    }
    mouse.x = x;
    mouse.y = y;
    return mouse;
}

四. 触摸事件

触摸事件与鼠标事件相似,一个触摸点可以被想象成一个鼠标光标。不过鼠标光标会一直停留在屏幕上,而受制却会从设备上按下、移动以及释放同一时间可能发生多点触摸,某个触摸点会保存在触摸事件的一个数组中,不过一般都建议使用第一个触摸点。

常用到的触摸事件有:

  • touchstart
  • touchend
  • touchmove

五. 触摸位置

其中,touchstarttouchmove事件的第一个触摸点位置为:

event.touches[0]

touchend事件的第一个触摸点位置为:

event.changedTouches[0]
<canvas id="canvas" width="300" height="300" style="background: #ccc;"></canvas>

var canvas = document.getElementById("canvas");
canvas.addEventListener("touchstart", function(e) {
    var touches = e.touches ? e.touches[0] : e;
    touchstartPosition = {
        x : touches.pageX,
        y : touches.pageY
    };
});

canvas.addEventListener("touchmove", function(e) {
    var touches = e.touches ? e.touches[0] : e;
    touchmovePosition = {
        x : touches.pageX,
        y : touches.pageY
    };
    console.log(touchmovePosition);
});

canvas.addEventListener("touchend", function(e) {
    var changedTouches = e.changedTouches ? e.changedTouches[0] : e;
    touchsEndPosition = {
        x : changedTouches.pageX,
        y : changedTouches.pageY
    };
    console.log(touchsEndPosition);
});

六. 键盘事件

键盘事件仅有两个:

  • keydown
  • keyup

七. 键盘码

在一个键盘事件中,可以通过事件对象的keyCode属性获知哪个键按下。

具体的键盘码可参考: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

八. 拖拽事件

  • dragstart
  • drag
  • dragenter
  • dragover
  • dragleave
  • drop
  • dragend

拖拽事件的具体用法可参考我的另一篇笔记:http://www.dengzhr.com/frontend/html/927

本文作者:子匠_Zijor,转载请注明出处:http://www.dengzhr.com/js/945