Event

Event模型主要包括Event接口本身的描述以及在DOM节点上注册的事件

事件流

事件捕获

事件冒泡

事件目标阶段

事件处理程序

DOM0级事件处理方式

DOM2级事件处理程序

浏览器差异

在IE10及以下版本中,只支持事件冒泡,在IE11中同时支持事件捕获与事件冒泡。在IE10及以下版本中,通过以下方法添加和删除事件。

  element.attachEvent("on"+ eventName, handler);  //添加事件处理程序
  element.detachEvent("on"+ eventName, handler);  //删除事件处理程序

在IE11及其他非IE浏览器中,同时支持事件捕获和事件冒泡两个过程,通过以下方法添加和删除事件

  addEventListener(eventName, handler, useCapture);       //添加事件处理程序
  removeEventListener(eventName, handler, useCapture);    //删除事件处理程序

其中的useCapture参数表示是否支持事件捕获,true表示支持事件捕获,false表示支持事件冒泡。默认状态为false

共性与不同处以及兼容性处理

(1)在DOM2级事件处理程序中,不管是IE浏览器还是非IE浏览器都支持对同一个事件绑定多个处理函数

var handler1 = function (){}
var handler2 = function (){}
---------------IE10及以下------------------
btn.attachEvent('onclick', handler1);
btn.attachEvent('onclick', handler2);
  
---------------IE11及非IE-----------------
btn.addEventListener('click', handler1);
btn.addEventListener('click', handler2);
<!-- 在id为wrap元素上点击会先后alert出123和456 -->
var wrap = document.getElementById('wrap');

wrap.addEventListener('click', function() {
    alert('123');
}, false);

wrap.addEventListener('click', function () {
    alert('456');
}, false);

(2)在需要删除绑定的事件时,不能删除掉匿名函数。意思是说添加和删除的必须是同一个函数。

var wrap = document.getElementById('wrap');
var outer = document.getElementById('outer');
var inner = document.getElementById('inner');

var handler = function () {
    alert('789');
};

// 第一中方式绑定和取消的是同一个函数,因此可以取消绑定的事件
wrap.addEventListener('click', handler, false);

wrap.removeEventListener('click', handler);

//第二种方式采取的是匿名函数的形式,则不会取消其绑定的click事件
wrap.addEventListener('click', function () {
    alert('123');
}, false);

wrap.removeEventListener('click', function () {

});

(1)在使用attachEvent为同一个事件添加多个事件处理函数时,按照添加的相反顺序执行

  //以下代码先alert出hello world,后alert出clicked
  var btn=document.getElementById("mybtn");   
  btn.attachEvent("onclick",function(){   
       alert("clicked");   
  });   
  btn.attachEvent("onclick",function(){  
       alert("hello world!");   
  }); 

(2)在使用attachEvent添加的事件处理程序会在全局作用域中运行,因此this指向全局作用域window。而通过addEventListener添加的事件处理程序在指定的元素内部执行,this指向绑定的元素。

var EventUtil = {
    addEventHandler: function(element, type, handler){
        if(element.addEventListener){
            element.addEventListener(type, handler);
        }else if(element.attachEvent){
            element.attachEvent("on" + type, handler);
        }else{
            element["on" + type] = handler;
        }
    },
    removeEventHandler:function(element, type, handler){
        if(element.addEventListener){
            element.removeEventListener(type, handler);
        }else if(element.detachEvent){
            element.detachEvent("on" + type, handler);
        }else{
            element["on"+type] = null;
        }
    }
}

事件捕获和事件冒泡处理过程

根据定义事件的规则不同,事件处理过程也将会不同。如果同时定义了事件捕获和事件冒泡,则会按照先捕获后冒泡的顺序,在目标阶段则按照事件定义的先后顺序执行。

实例:DOM2Event.html

DOM3级事件处理程序

DOM3级事件处理程序是在DOM2级事件的基础上重新定义了事件,也添加了一些新的事件。最重要的区别是DOM3允许自定义事件,自定义事件可以由createEvent("CustomEvent")方法创建,返回的对象有一个initCustomEvent()

方法接收如下四个参数。

可以像分配其他事件一样在DOM中分派创建的自定义事件对象。如:

var  div = document.getElementById("myDiv");
EventUtil.addEventHandler(div,"myEvent", function () {
    alert("div myEvent!");
});
EventUtil.addEventHandler(document,"myEvent",function(){
    alert("document myEvent!");
});
if(document.implementation.hasFeature("CustomEvents","3.0")){
    var e = document.createEvent("CustomEvent");
    e.initCustomEvent("myEvent",true,false,"hello world!");
    div.dispatchEvent(e);
}

这个例子中创建了一个冒泡事件“myEvent”。而event.detail的值被设置成了一个简单的字符串,然后在div和document上侦听该事件,因为在initCustomEvent中设置了事件冒泡。所以当div激发该事件时,浏览器会将该事件冒泡到document。

实例:

var myDiv = document.getElementById('myDiv');
EventUtil.addEventHandler(myDiv, 'myEvent', function () {
    alert('myDiv clicked');
});

EventUtil.addEventHandler(document, 'myEvent', function (e) {
    alert('document clicked');
    console.log(e);
});

if(document.implementation.hasFeature('CustomEvent', '3.0')) {
    var e = document.createEvent('CustomEvent');
    e.initCustomEvent('myEvent', true, false, {name: '13'});
    myDiv.dispatchEvent(e);
    console.log(e.detail);  // {name: '13'}
}

参考资料:

https://segmentfault.com/a/1190000003497939

http://www.cnblogs.com/zichi/p/4713038.html

Event本身的属性和方法

构造方法

定义

示例

标准属性

bubbles

cancelable

target与currentTarget

defaultPrevented

eventPhase

isTrusted

type

非标准属性

以下属性都是非标准属性,不建议在生产环境中使用

explicitOriginalTarget

originalTarget

srcElement

timeStamp

方法

createEvent()

initEvent()

preventDefault()

stopImmediatePropagation

stopPropagation

常用事件类型

Focus事件

focus事件
blur事件
focusin与focusout
事件执行顺序
focusable 元素

Mouse事件

点击相关
鼠标移动相关
滚轮相关

键盘事件

拖拽事件

拖放基础

在一个web页面中,有一些默认的可拖拽元素,包括选中的文本,image图片和超链接。除了这些元素外,其他元素默认是不可拖拽的,为了能让其他元素也能拖拽,必须进行以下三步:

在拖拽过程中发生的事件:

拖拽通常有以下几个步骤:

实现将列表内容拖拽进垃圾箱的一次完整演示

移动端事件

移动端事件主要指的是TouchEvent,这类事件用来响应用户对触摸屏或者触摸板的操作。每个touch对象代表一个触点,每个触点都由其位置,大小,形状,压力大小和目标element描述。

接口
触摸事件TouchEvent
完整的触摸事件的例子-使用canvas进行画图