DOM类的相关信息
一、DOM事件级别(DOM标准定义的级别)
DOM0 element.onclick = function(){}
DOM2 element.addEventListener('click',function(){},false) ie中:btn.attachEvent('onclick',handler); function handler(e){ alert(this); // window }
DOM2 element.addEventListener('keyup',function(){},false) 用法和上面的一样,只不过dom3中多加了一些鼠标和键盘事件。
二、DOM事件模型
事件模型分为:捕获和冒泡
三、事件流
DOM2级事件规定的事件流的三个阶段:捕获,目标,冒泡(IE8以及更早版本不支持DOM事件流);
四、事件捕获的具体流程
捕获流程:windonw ------> document ------------->html ---------->body ---------->.... -------------->目标元素
冒泡流程:目标元素 ----------> body ----------> html ----------> document ----------> windonw
五、Event对象的常见应用
event.preventDefault();//阻止默认行为 event.stopPropagation();//阻止冒泡流 event.stopImmediatePropagation();//一个控件上定义多个事件,在前面的事件中调用这个事件,会阻止后台的事件执行 event.currentTarget(); //监听事件的元素 event.target();//获取当前被点击的元素,ie中用的是srcElement
能过这个以中延伸一个场景:事件委托
事件委托:用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上,利用冒泡的原理,把事件加到父级上,触发执行效果。
</span><ul id="parent-list"> </span><li id="post-1">Item 1</span></li> </span><li id="post-2">Item 2</span></li> </span><li id="post-3">Item 3</span></li> </span><li id="post-4">Item 4</span></li> </span><li id="post-5">Item 5</span></li> </span><li id="post-6">Item 6</span></li> </span></ul>
function getEventTarget(e) { e = e || window.event; return e.target || e.srcElement; } // 获取父节点,并为它添加一个click事件 document.getElementById_x("parent-list").addEventListener("click",function(e) { // 检查事件源e.targe是否为Li var target = getEventTarget(e); if(target && target .nodeName.toUpperCase == "LI") { // 真正的处理过程在这里 console.log("List item ",e.target.id.replace("post-")," was clicked!"); } });
优点
通过上面的介绍,大家应该能够体会到使用事件委托对于web应用程序带来的几个优点:
1.可以大量节省内存占用,减少事件注册。
2.可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。
3.JavaScript和DOM节点之间的关联变少了,这样也就减少了因循环引用而带来的内存泄漏发生的概率。
缺点
不是所有的事件都能冒泡的。blur、focus、load和unload不能像其它事件一样冒泡。事实上blur和focus可以用事件捕获而非事件冒泡的方法获得(在IE之外的其它浏览器中)。
在管理鼠标事件的时候有些需要注意的地方。如果你的代码处理mousemove事件的话你遇上性能瓶颈的风险可就大了,因为mousemove事件触发非常频繁。而mouseout则因为其怪异的表现而变得很难用事件代理来管理。
六、自定义事件
var EventTarget = function(argument) { this._listener = {}; } EventTarget.prototype = { constructor: this, addEvent: function(type,fn){ if(typeof type === "string" && typeof fn==="function"){ this._listener[type] = [fn]; }else{ this._listener.push(fn); } }, fireEvent:function(type){ var events = { type:type, target: this } if(type && this._listener[type]){ for (var length = this._listener[type].length,start= 0;start<length;start++) { this._listener[type][start].call(this,events); } } }, removeEvent:function(type){ var listeners = this._listener[type]; if(listeners instanceof Array){ delete this._listener[type] } return this; } }
对它的使用是
//------------- 以下为测试代码 --------
var myEvents = new EventTarget(); myEvents.addEvent( "once", function(a,b,c) { console.log(a) console.log(b) console.log(c) this.removeEvent("once"); }); document.onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement; if (!target || !/input|pre/i.test(target.tagName)) { myEvents.fireEvent("once"); } };
还有一种办法,但是兼容性不是特别好
var event_ = new Event('myEvent'); element.addEventListener('myEvent',function(){ console.log("....") }) element.dispatchEvent(event_);
参考 :http://www.zhangxinxu.com/study/201203/js-custom-events-prototypal.html