event 对象 小记

时间:2023-03-31 21:57:32

event对象的属性提供了有关事件的细节并且通过event对象的方法,可以控制事件的继续传播和阻止事件的默认行为

2级DOM Events 标准定义了一个标准的事件模型  被除了IE外的所有现代浏览器实现     在标准事件模型中event对象传递给事件句柄函数,在处理事件的时候获取事件发生的一些属性和控制事件的一些行为(冒泡和默认行为)   在标准事件模型中,Event的各种子接口定义了额外的属性,也就是可以定义多种种类的event对象  而IE只有一种event对象 应用于所有的事件处理

2级DOM event对象支持的方法

属性 描述
bubbles 指定事件是否起泡
cancelable 是否取消事件的默认行为
currentTarget 返回事件监听器触发该事件的元素
eventPhase 返回事件传播的当前阶段
target 事件的目标节点
timeStamp 返回事件生成的时间和日期
type 返回event表示的事件名称

区分currentTarget 和 target  在dom事件流中是结合了两种事件流的  事件捕获 和 事件冒泡

    <div>
<button> test</button>
</div>

比如上面的结构   对于button的click事件的响应  是这样的传播过程  先是捕获阶段   从外层的div向下传播 此时的event.Phase是1     传播到目标节点  此时的event.Phase是2

然后冒泡 在向上传递到外层的div 此时的event.phase是3    触发该事件的元素就是event.target   实际处理该事件的元素就是event.currentTaget  同样是上面的例子 对于btn的click 事件 有可能在捕获阶段子外层div上进行处理   触发事件是点击的button(event.target)  处理的是外层的div(event.currentTarget)   具体的例子 请看这篇blog

js事件小记

2级DOM event对象 支持的方法

方法  描述
iniEvent 初始化新创建的event对象属性
preventDefault 阻止事件的默认行为(event对象的cancelable属性)
stopPropagation 阻止事件的进一步传播

这里的preventDefault() 和  stopPropagation() 很好理解   主要介绍下 initEvent()方法  该方法用于初始化新事件对象的属性   新事件对象?     先跳转下

可以通过document.createEvent(eventType) 来创建新的事件对象

参数 事件接口 初始化方法
HTMLEvents HTMLEvent initEvent
MouseEvents MouseEvent initMouseEvent
UIEvents UIEvent initUIEVent

也就是我们想创建一个新的HTML事件对象  可以通过这样的方式

    var evt = document.createEvent('HTMLEvents');

我们创建了新的事件对象后就可以对事件的属性进行设置(关于UIEvents还不大了解 欢迎交流)   跳转回来

在创建了新的event事件对象后 ,调用iniEvent()方法来初始化新事件对象的属性  iniEvent(eventType,canBubble,cancelable)

参数1  事件类型  click等   参数2    是否冒泡   参数3 cancelable 是否可以通过preventDefault()取消默认的行为

在创建完新的事件对象后 就要通过element.dispatchEvent(event) 方法来分派刚才创建的合成事件(也就是在特定的元素上触发我们刚才创建的事件)

下面通过一个完整的例子来简单的说明上面的方法的使用

在页面中有这样的一个超链接

<a href="https://www.baidu.com"  id="test">baidu</a>

相应的js如下

    var btn = document.getElementById('test');
btn.addEventListener('click',function(e){
console.log(1);
e.preventDefault(); })//在超链接上监听click事件
var evt = document.createEvent('HTMLEvents'); //创建新的事件对象
evt.initEvent('click',false,true); //配置新创建的事件对象 这里的设置是不冒泡 可以通过event.preventDefault()取消默认行为
btn.dispatchEvent(evt);//在btn上分派事件

在页面中可以看见响应了分派的click事件  并且没有进行页面的跳转

那么将initEvent()的第三个参数设置为false的时候呢

    var btn = document.getElementById('test');
btn.addEventListener('click',function(e){
console.log(1);
e.preventDefault(); })
var evt = document.createEvent('HTMLEvents');
evt.initEvent('click',false,false); //这里配置成不可以通过event.preventDefault() 取消默认的行为
btn.dispatchEvent(evt);

会发现同样响应了click事件  但是页面发生了跳转    也就是event.preventDefault()没有起作用   这种情况下调用event.preventDefault() 并不会报错 只是没作用

2016.5.4  刚看到一个时间戳对委托事件处理的例子 拿过来分享

  <div id="test">
<input type="text" id="abc" name="abc" />
<label for="abc">1111</label>
</div>

上面的例子中我通过委托在外层的id为test的div上绑定click事件的时候,但我们单击label的时候会冒泡一次,响应外层的click事件,又由于label是跟input相关联,会触发input的click事件,input的click事件冒泡,触发外层的click,也就造成了触发两次的情况,如何在不修改结构,也就是lable关联的情况下,只响应当前单击的元素的事件呢

时间戳

   var evTimeStamp = 0;
document.getElementById("test").onclick = function(e) {
var now = +new Date();
if (now - evTimeStamp < 100) {
return;
}
evTimeStamp = now;
console.log(e.target);
}


这个思路就是如果当前元素去触发别的元素的click事件,now-evTimeStamp的时间会小于设置的时间100 就不会响应

具体参考  单击labe时click事件被触发两次的坑