邹洋的博客

Don't be the same, be better !

zouyang0921's avatar zouyang0921

JavaScript:事件对象

  在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

  所有浏览器都支持 event 对象,但支持方式不同。

DOM中的事件对象

  兼容 DOM 的浏览器会将一个 event 对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法(DOM0 级或 DOM2 级),都会传入 event 对象。

var btn = document.getElementById('myBtn');
btn.onclick = function(event) {
    alert(event.type);     // click
};

btn.addEventListener('click', function(event) {
    alert(event.type);     // click
}, false);

  在通过 HTML 特性指定事件处理程序时,变量 event 中保存着 event 对象。

<input type="button" value="Click Me" onclick="alert(event.type)"/>

  event 对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。不过,所有事件都会有下表列出的成员。

属性/方法 类 型 读/写 说明
bubbles Boolean 只读 表明事件是否冒泡
cancelable Boolean 只读 表明是否可以取消事件的默认行为
currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素
defaultPrevented Boolean 只读 为 true表示已经调用了preventDefault()(DOM3级事件中新增)
detail Integer 只读 与事件相关的细节信息
eventPhase Integer 只读 调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段
preventDefault() Function 只读 取消事件的默认行为。如果 cancelable 是 true,则可以使用这个方法
stopImmediatePropagation() Function 只读 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3 级事件中新增)
stopPropagation() Function 只读 取消事件的进一步捕获或冒泡。如果 bubbles 为 true,则可以使用这个方法
target Element 只读 事件的目标
trusted Boolean 只读 为true表示事件是浏览器生成的。为 false 表示事件是由开发人员通过JavaScript创建的(DOM3级事件中新增)
type String 只读 被触发的事件的类型
view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的 window 对象

在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this,currentTarget 和 target 包含相同的值。

var btn = document.getElementById('myBtn');
btn.onclick = function(event) {
    alert(event.currentTarget === this);     // true
    alert(event.target === this);            // true
}; 

如果事件处理程序存在于按钮的父节点中(例如 document.body),那么这些值是不相同的。

document.body.onclick = function(event) {
    alert(event.currentTarget === document.body);    // true
    alert(this === document.body);    // true
    alert(event.target === document.getElementById('myBtn')); // 点击'myBtn',结果为true;点击body,结果为false
};

注:只有在事件处理程序执行期间, event 对象才会存在;一旦事件处理程序执行完成, event 对象就会被销毁。

IE中的事件对象

  与访问 DOM 中的 event 对象不同,要访问 IE 中的 event 对象有几种不同的方式,取决于指定事件处理程序的方法。

  • 在使用 DOM0 级方法添加事件处理程序时, event 对象作为 window 对象的一个属性存在。
    var btn = document.getElementById('myBtn');
    btn.onclick = function() {
      var event = window.event;
      alert(event.type);    // click
    };
    
  • 在使用 DOM2级方法 添加事件处理程序时, event 对象作为参数被传入事件处理程序函数中。
    var btn = document.getElementById('myBtn');
    btn.attachEvent('onclick', function(event) {
      alert(event.type);    // click
    });
    
  • HTML特性 指定的事件处理程序中,通过 event 变量来访问 event对象(与 DOM中的事件模型相同)。
    <input type="button" value="Click Me" onclick="alert(event.type)">
    
      IE 的 event 对象同样也包含与创建它的事件相关的属性和方法。其中很多属性和方法都有对应的或者相关的 DOM属性和方法。所有事件对象都会包含下表所列的属性和方法:
属性/方法 类 型 读/写 说明
cancelBubble Boolean 读/写 默认值为 false,但将其设置为 true,就可以取消事件冒泡(与DOM中的 stopPropagation() 方法的作用相同)
returnValue Boolean 读/写 默认值为 true,但将其设置为 false,就可以取消事件的默认行为(与DOM中的 preventDefault() 方法的作用相同),但没有办法确定事件是否能被取消
srcElement Element 只读 事件的目标(与DOM中的 target 属性相同)
type String 只读 被触发的事件的类型

跨浏览器的事件对象

var EventUtil = {
    getEvent: function(event) {
        return event ? event : window.event;
    },

    getTarget: function(event) {
        return event.target || event.srcElement;
    },

    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    },

    addHandler: function(element, type, handler) {            
        if (element.addEventListener) { 
            element.addEventListener(type, handler, false); 
        } else if (element.attachEvent) {                    
            element.attachEvent('on' + type, handler);
        } else {
            element['on' + type] = handler;             
        }
    },  

    removeHandler: function(element, type, handler) { 
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    }
};