解析模拟事件

昨晚在《Javascript权威指南》书本中看到了“合成事件”这样的一个名词,开始怎么都不明白,看了它提供的例子,也都是糊里糊涂,不知道这样使用有什么作用,直到今天,上网几番查找,都没有讨论它的用处,都是简单介绍了createEvent,createEventObject等等方法的语法,都没有现成Demo来说明它的用途。时间从上午到了下午,最后还是回到了书本中,又重新看了一下《Javascript权威指南》中提供的例子,照着书本写例子来测试,第一次发现可以动态声明事件,类似于addEventListener和attachEvent的用途,发现的端倪,继续深入。之后继续上网查资料,发现了“模拟事件”,这个名词,哟和!!突然有些豁然开朗,对,“模拟事件”,因此就尝试在HTML元素行内声明事件,之后用createEvent和createEventObject生成新事件,在window.onload回调函数下测试,模拟成功!终于明白了它的这一点用途了,也开始想到了jQuery中的trigger函数的原理了!

下面来看看我写的一个封装的imitateEvent对象:

/*
elem:是DOM元素引用,将要添加模拟事件的DOM元素
eventType:需要模拟的事件的类型
handler:事件回调函数,这个函数可有可无。
*/
var imitateEvent = {};
imitateEvent.imitate = function(elem, eventType, handler){
    elem = typeof elem !== "object" ? document.getElementById(elem) : elem;
    //处理W3C下createEvent的第一个参数的设置,它有三种类型:Events,MouseEvents以及UIEvents
    //不过UIEvents非常少用,在此就不提供模拟这些事件
    //在这里声明Events和MouseEvents对象的目的是确定适用Events类型还是MouseEvents类型
    var Events = {
        "click": "click",
        "blur": "blure",
        "change": "change",
        "dblclick": "dblclick",
        "error": "error",
        "focus": "focus",
        "keypress": "keypress",
        "keydown": "keydown",
        "keyup": "keyup",
        "load": "load",
        "resize": "resize",
        "scroll": "scroll",
        "select": "select",
        "submit": "submit",
        "unload": "unload"
    };
    var MouseEvents = {
        "mousedown": "mousedown",
        "mousemove": "mousemove",
        "mouseout": "mouseout",
        "mouseover": "mouseover",
        "mouseup": "mouseup"
    };
    var evt = null;
    if (document.createEvent) { // W3C DOM
        //通过createEvent创建一个新事件,默认是Events
        evt = document.createEvent(Events[eventType] ? "Events" : MouseEvents[eventType] ? "MouseEvents" : "Events");
        //初始化事件
        evt.initEvent(eventType, true, false);
        //分派事件
        elem.dispatchEvent(evt);
		//如果没有提供handler函数,则默认用一个空函数代替,下面IE中也是这样设置
        elem.addEventListener(eventType, handler ? handler : function(){}, false);
    } else if (document.createEventObject) { // IE
        //通过createEventObject创建一个新事件
        evt = document.createEventObject();
        //分派事件
        elem.fireEvent("on" + eventType, evt);
      elem.attachEvent("on" + eventType, handler ? function(){ handler.call(elem);} : function(){});
    }
}

如果在DOM元素已经通过其他方式添加了事件的时候,在模拟事件对象中又提供了handler回调函数,则事件则会叠加,可能这就是所谓的“合成事件”吧。

下面是提供的Demo:

<div id="div" onclick="test();">
       Click me please.
</div>
<script type="text/javascript">
    //添加事件模拟,这样在window.onload的时候就调用了div标签的onclick事件
     //在这里提供了handler回调函数,如果没有提供的话,就只会执行其他方式声明的事件。
    imitateEvent.imitate(document.getElementById("div"), "click", function(){
       alert(this.nodeName);
    });
    function test(){
       alert("You have mouseovered me already.");
    }
</script>

上面我对于模拟事件的一点点见解,如果有错误之处,还请高手指点一二,指正错误,不胜感激!