一、添加事件
方法一:直接将事件脚本内嵌XHTMl中(弹出‘clicked’)
<input type="button" onclick="alert('clicked');" value="click me"/>
方法二:将事件脚本独立于函数(弹出‘clicked’)
<input type="button" onclick="clickEvent();" value="click me" /> <script type="text/javascript"> function clickEvent() { alert("clicked"); } </script>
方法三:行为结构完全分离(弹出‘clicked again’,仅会执行最后那个绑定的事件),此方法一个元素的同一事件只允许一个处理器,仅会执行一次。
<input type="button" id="Example" value="click me" /> <script type="text/javascript"> var btn = document.getElementById("Example"); btn.onclick = function () { alert("clicked"); }; btn.onclick = function () { alert("clicked again"); }; </script>
方法四:监听事件(IE6,IE7,IE8,依次弹出‘clicked again’、‘clicked’,其他浏览器,依次弹出‘clicked’、‘clicked again’),原因是W3C标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而IE的attachEvent方法则相反,后注册的事件先觖发,先注册的事件后触发。
<input type="button" id="Example" value="click me" /> <script type="text/javascript"> function addEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener) { eventTarget.addEventListener(eventType, evrntHandler, false); } else if (eventTarget.attachEvent) { eventType = "on" + eventType; eventTarget.attachEvent(eventType, evrntHandler) } else { eventTarget["on" + eventType] = evrntHandler; } } var btn = document.getElementById("Example"); addEvent(btn, "click", function () { alert("clicked"); }); addEvent(btn, "click", function () { alert("clicked again"); }); </script>
综上,在添加事件中,方法四是最佳选择。
二、阻止事件冒泡
事件在嵌套函数中会传播,在以下代码中,点击inner,依次弹出‘inner’、‘middle’、‘out’,点击middle,依次弹出‘middle’、‘out’,点击out,弹出‘out。addEventListener(event,function,capture/bubble)函数的第三个参数: true表示在捕获阶段,false表示在冒泡阶段。为了兼容IE的事件处理,所以设置为false,如果第三个参数设置为true,在标准浏览器中,点击inner,依次弹出‘out’、‘middle’、‘inner’。
<script type="text/javascript"> function addEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener) { eventTarget.addEventListener(eventType, evrntHandler, false); } else if (eventTarget.attachEvent) { eventType = "on" + eventType; eventTarget.attachEvent(eventType, evrntHandler) } else { eventTarget["on" + eventType] = evrntHandler; } } addEvent(window, "load", function () { var out = document.getElementById("out"); var middle = document.getElementById("middle"); var inner = document.getElementById("inner"); addEvent(out, "click", function () { alert("out") }) addEvent(middle, "click", function () { alert("middle") }) addEvent(inner, "click", function () { alert("inner") }) }); </script> <div style="padding:20px;background:red" id="out"> <div style="padding:20px;background:green" id="middle"> <div style="padding:20px;background:white" id="inner"> </div> </div> </div>
如何阻止事件传播?以下代码可以解决,点击inner,弹出‘inner’,点击middle,弹出‘middle’,点击out,弹出‘out’
<script type="text/javascript"> function addEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener) { eventTarget.addEventListener(eventType, evrntHandler, false); } else if (eventTarget.attachEvent) { eventType = "on" + eventType; eventTarget.attachEvent(eventType, evrntHandler) } else { eventTarget["on" + eventType] = evrntHandler; } } function cancelPropagation(event) { event = window.event || event; if (document.all) { event.cancelBubble = true; } else { event.stopPropagation(); } } addEvent(window, "load", function () { var out = document.getElementById("out"); var middle = document.getElementById("middle"); var inner = document.getElementById("inner"); addEvent(out, "click", function () { alert("out") }) addEvent(middle, "click", function (evt) { alert("middle"); cancelPropagation(evt); }); addEvent(inner,"click",function(evt){ alert("inner"); cancelPropagation(evt); }); }); </script> <div style="padding:20px;background:red" id="out"> <div style="padding:20px;background:green" id="middle"> <div style="padding:20px;background:white" id="inner"> </div> </div> </div>
如果想解除相应的绑定事件,我们可以用以下代码解决。
<script type="text/javascript"> function addEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener) { eventTarget.addEventListener(eventType, evrntHandler, false); } else if (eventTarget.attachEvent) { eventType = "on" + eventType; eventTarget.attachEvent(eventType, evrntHandler) } else { eventTarget["on" + eventType] = evrntHandler; } } function removeEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.removeEventListener) { eventTarget.removeEventListener(eventType, evrntHandler, false); } else if (eventTarget.detachEvent) { eventType = "on" + eventType; eventTarget.detachEvent(eventType, evrntHandler) } else { eventTarget["on" + eventType] = null; } } addEvent(window, "load", function () { var ok = document.getElementById("ok"); var switchBtn = document.getElementById("switchBtn"); var flag = true; addEvent(switchBtn, "click", function () { if (flag) { addEvent(ok, "click", show); switchBtn.value = "removeEvent"; flag = false; } else { removeEvent(ok, "click", show); switchBtn.value = "addEvent"; flag = true; } }); }); function show() { alert("I am here"); } </script> <input type="button" value="addEvent" id="switchBtn" /><input type="button" value="Try to click me^_^" id="ok" />
三、其他区别
1、 DOM标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而attachEvent方法则相反–后注册的事件先觖发,先注册的事件后触发;
2、 DOM标准的浏览器文本节点也会冒泡,而IE内核的浏览器文本节点不会冒泡;
3、 DOM标准的浏览器事件对象与IE内核的浏览器事件不同。