JS事件简单总结

也称DOM0事件处理方式,DOM0不是W3C的标准,由于历史发展的原因,它存在过也一直存在着。很简单,只要在html元素中添加on+事件的属性即可。

或者用js的方式给元素添加这个属性。

var btEle = document.getElementById(‘myButton’);
btEle.onclick = doSomething;

这样的优点是简单方便,并且兼容所有的浏览器;缺点也不少,违反了行为与表现分离的准则,只能添加一个事件,也不能利用事件委托机制去更多的事。


IE事件实现方式

上文提到IE8及其以下的事件传播机制只有冒泡,没有捕获,实现方式为

//监听事件
element.attachEvent(‘on’ + eventType, callback);
//解除监听
element.detachEvent(‘on’ + eventType, callback);
//手动触发事件,兼容性IE6-10
element.fireEvent(‘on’ + eventType)

需要注意的是,匿名函数无法被解除监听。


标准事件实现方式(DOM2)

DOM2规定的标准应该大一统了浏览器,而之后变得不多。目前W3C最新的标准是15年出的DOM4。我们来简单看下。

//监听事件
element.addEventListener(eventType, callback, useCapture);
//解除监听
element.removeEventListener(eventType, callback, useCapture);
//手动触发事件
element.dispatchEvent(eventType)
//回调函数中有个event对象记录事件的属性
function callback(event){
//do something
}

因为标准的事件传播机制有捕获和冒泡阶段,这里最后一个参数useCapture表示是否在事件捕获阶段就执行回调函数,默认为false。一般情况下,我们使用默认值,即在事件冒泡阶段执行函数。为什么?主要是为了兼容旧版的IE。


事件常见属性

我们已经知道,事件的回调函数中有个事件对象的参数。从第一部分,我们已经看到Event对象的继承关系,比如我们最常见的鼠标事件或者键盘事件,MouseEvent继承自UIEvent,UIEvent继承自Event。我们参考最新的W3C规范,来具体看下。

[Constructor(DOMString type, optional EventInit eventInitDict),
Exposed=(Window,Worker)]
interface Event {
// 事件的类型,比如click,submit,load等
readonly attribute DOMString type;
// 触发事件的那个目标元素
readonly attribute EventTarget? target;
// 事件传播所在的当前元素
readonly attribute EventTarget? currentTarget;
const unsigned short NONE = 0;
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
// 事件所在的阶段,枚举值如上
readonly attribute unsigned short eventPhase;
// 阻止事件的冒泡,在当前元素的冒泡执行完之后
void stopPropagation();
// 立即阻止冒泡,包括当前元素还有其他的回调事件
// DOM3增加新属性
void stopImmediatePropagation();
// 是否在冒泡阶段
readonly attribute boolean bubbles;
// 是否可以被取消,用preventDefault取消
readonly attribute boolean cancelable;
// 取消当前元素的默认事件,前提是cancelable为true
void preventDefault();
// 是否被preventDefault过,DOM3增加新属性
readonly attribute boolean defaultPrevented;
// 事件是否有用户触发的
[Unforgeable] readonly attribute boolean isTrusted;
// 当前时间戳
readonly attribute DOMTimeStamp timeStamp;
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
};

dictionary EventInit {
boolean bubbles = false;
boolean cancelable = false;
};

[Constructor(DOMString type, optional MouseEventInit eventInitDict)]
interface MouseEvent : UIEvent {
// 相对屏幕的x,y坐标
readonly attribute long screenX;
readonly attribute long screenY;
// 相对浏览器可视区域的x,y坐标
readonly attribute long clientX;
readonly attribute long clientY;
//是否按下这些特殊的键
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
//哪个鼠标键被按下,0主键,1滚轮,2附键,只在mouseup,mousedown事件中有效
readonly attribute short button;
// 被激活的鼠标,可以是多个,0没有,1主键,2附键,4滚轮,8后退?,16前进?
// 还可以相加,比如按下了主键和滚轮,就是1+4 = 5
readonly attribute unsigned short buttons;
readonly attribute EventTarget? relatedTarget;
boolean getModifierState(DOMString keyArg);
};

以上是规范,但实际上浏览器的实现上好像还有很多杂七杂八的属性。以下是在Chrome 56输出的结果。


MouseEvent

感觉眼睛都要花了,比较常用的感觉不多,也看场景吧。一般比如target,preventDefalut,stopPropagation,type,以及坐标的属性比较常用吧。

由于浏览器的历史原因,关于鼠标坐标的属性真是好多对:

属性描述x, y在整个浏览器窗口所处的位置screenX, screenY在整个屏幕中所处于位置clientX, clientY在整个浏览器窗口所处的位置,与x, y属性相同layerX, layerY在整个元素的区域鼠标的位置(但算上了scroll的距离),当不随页面滚动而变化pageX, pageY在整个页面所处的位置,当不随页面滚动而变化offsetX, offsetY在整个元素的区域,鼠标的位置,当不随页面滚动而变化movementX, movementY两个事件之间鼠标的位移差

最好使用W3C规范里面的两对属性,是最安全和最保险的选择,screenX, screenY, clientX, clientY。

简单的兼容实现

主要是考虑对IE8及其以下的兼容性。

function addEventListener(target, event, callback)
if( window.addEventListener ){
target.addEventListener(event, callback)
}
else if(window.attachEvent){
target.attachEvent(‘on’ + event, callback);
}

结尾

学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

html5

js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

html5

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值