1.DOM0事件模型 (支持率:浏览器)
俩种写法
document.getElementById("test").onclick = function(e){}; document.getElementById("test")["onclick"] = function(e){};
基于DOM0的事件,对于同一个dom节点而言,只能注册一个,后边注册的同种事件会覆盖之前注册的。例如:
var btn = document.getElementById("test"); btn.onclick = function (e) { console.log("ok1"); }; btn["onclick"] = function (e) { console.log("ok2"); }
结果会输出ok2。
接下来再说说this。事件触发时,this就是指该事件在哪个dom对象上触发。例如:
var btn = document.getElementById("test"); btn.onmousemove = function(e){ console.log(this.id); };
结果会输出 test,this代表这个dom节点。
解除事件就相当简单了,只需要再注册一次事件,把值设成null。
var btn = document.getElementById("test"); btn.onclick = function(e){ console.log("ok"); }; btn.onclick = null;
DOM0事件模型还涉及到直接写在html中的事件。
<div id="test" onclick="test();" ></div>
通过这种方式注册的事件,同样遵循覆盖原则,同样只能注册一个,最后一个生效。区别就是,这样注册的事件,this指向的是window,不再是触发事件的dom对象。想要操作dom对象,需自己传入this。
<button id="test" onclick="test(this);">按钮</button> function test(obj) { console.log(obj.id); }
结果会输出 test,obj代表这个dom节点。
2.DOM2事件模型
DOM2事件通过addEventListener和removeEventListener,兼容IE8及其以下版本浏览器,对应的attachEvent和detachEvent。
事件兼容写法 例如:
if (traget.addEventListener) { traget.addEventListener('click', function (e) { }, false); } else { traget.attachEvent('click', function (e) { }, false) }
事件名相对于dom0去掉了on。
事件绑定addEventListener
var btn = document.getElementById("test"); btn.addEventListener("click", function(e){ console.log("ok"); }, false);
事件移除addEventListener
var btn = document.getElementById("test"); //将回调存储在变量中 var func = function(e){ console.log("ok"); }; //绑定 btn.addEventListener("click", func , false); //解除 btn.removeEventListener("click", func , false);
3.捕获事件和冒泡事件
示意图:
<body> <div id="testParent" class="test">2 <button id="test" >按钮</button> </div> </body>
var btn = document.getElementById("test"); //捕获事件 btn.addEventListener("click", function(e){ console.log("ok1"); }, true); //冒泡事件 btn.addEventListener("click", function(e){ console.log("ok2"); }, false); 结果是: ok1 ok2 同一个DOM元素绑定捕获和冒泡事件,事件执行顺序按绑定时的顺序。 var btn = document.getElementById("test"); var btnPt = document.getElementById("testParent"); //捕获事件 btnPt.addEventListener("click", function(e){ console.log("ok1"); }, true); //冒泡事件 btnPt.addEventListener("click", function(e){ console.log("ok3"); }, false); //冒泡事件 btn.addEventListener("click", function(e){ console.log("ok2"); }, false); 结果是: ok1 ok2 ok3 父级关系dom。先执行捕获事件,然后从元素本身开始执行冒泡事件,往父级元素依次执行。
当然冒泡事件是可以阻止的,e.stopPropagation()。
if ( e && e.stopPropagation ){ //因此它支持W3C的stopPropagation()方法 e.stopPropagation(); } else{ //否则,我们需要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; return false; }
js阻止默认事件:
if (e && e.preventDefault) { //阻止默认浏览器动作(W3C) e.preventDefault(); } else{ //IE中阻止函数器默认动作的方式 window.event.returnValue = false; return false; }