IE与非IE浏览器在事件绑定的执行顺序问题
2009-09-20 14:42
471 查看
原始的DOM1事件处理机制,是不能绑定多个处理函数。如一个元素在onclick事件先绑定一个函数,用来alert其id,然后再在相同的事件绑定另一个函数,用来alert其style。对不起,第二个函数会覆盖掉第一个,只会alert其style。于是.addEventListener() 与 .attachEvent()被分别开发出来了。为了屏蔽各浏览器的差异,javascript界举办了一个慈善邀请赛,鼓励大家提交各自addEvent/removeEvent 方案,最后由John Resig大神获得。
但是最近我在同一个元素绑定多个onclick事件时,发现些问题。
<!doctype html>
<title>javascript事件绑定 by 司徒正美</title>
<meta charset="utf-8"/>
<meta name="keywords" content="javascript事件绑定 by 司徒正美" />
<meta name="description" content="javascript事件绑定 by 司徒正美" />
<script type="text/javascript">
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj["e"+type+fn] = fn;
obj[type+fn] = function(){obj["e"+type+fn]( window.event );}
obj.attachEvent("on"+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
window.onload = function(){
var test = document.getElementById("test");
addEvent(test,"click",function(){
alert(1);
});
addEvent(test,"click",function(){
alert(2);
});
addEvent(test,"click",function(){
alert(3);
});
addEvent(test,"click",function(){
alert(4);
});
}
</script>
<h1 id="test">javascript事件绑定(点我)</h1>
运行代码
IE8与其他标准浏览器会弹出1,2,3,4,换言之,先进先出。IE6非先进先出,也不是后进先出,而是2,4,3,1。但如果我们绑定更多函数,IE8的执行顺序就有问题了,IE6与IE7更不用说。谁有好的解决方法吗?
后来,又发现Dean Edwards也修正了IE事件顺序错乱问题
function addEvent( obj, type, fn ) { if ( obj.attachEvent ) { obj["e"+type+fn] = fn; obj[type+fn] = function(){obj["e"+type+fn]( window.event );} obj.attachEvent("on"+type, obj[type+fn] ); } else obj.addEventListener( type, fn, false ); } function removeEvent( obj, type, fn ) { if ( obj.detachEvent ) { obj.detachEvent("on"+type, obj[type+fn] ); obj[type+fn] = null; } else obj.removeEventListener( type, fn, false ); }
但是最近我在同一个元素绑定多个onclick事件时,发现些问题。
<!doctype html>
<title>javascript事件绑定 by 司徒正美</title>
<meta charset="utf-8"/>
<meta name="keywords" content="javascript事件绑定 by 司徒正美" />
<meta name="description" content="javascript事件绑定 by 司徒正美" />
<script type="text/javascript">
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj["e"+type+fn] = fn;
obj[type+fn] = function(){obj["e"+type+fn]( window.event );}
obj.attachEvent("on"+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
window.onload = function(){
var test = document.getElementById("test");
addEvent(test,"click",function(){
alert(1);
});
addEvent(test,"click",function(){
alert(2);
});
addEvent(test,"click",function(){
alert(3);
});
addEvent(test,"click",function(){
alert(4);
});
}
</script>
<h1 id="test">javascript事件绑定(点我)</h1>
运行代码
IE8与其他标准浏览器会弹出1,2,3,4,换言之,先进先出。IE6非先进先出,也不是后进先出,而是2,4,3,1。但如果我们绑定更多函数,IE8的执行顺序就有问题了,IE6与IE7更不用说。谁有好的解决方法吗?
/** * addEvent & removeEvent -- cross-browser event handling * Copyright (C) 2006-2007 Dao Gottwald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Contact information: * Dao Gottwald <dao at design-noir.de> * * @version 1.2.1 */ function addEvent(o, type, fn) { o.addEventListener(type, fn, false); } function removeEvent(o, type, fn) { o.removeEventListener(type, fn, false); } /*@cc_on if (!window.addEventListener) { var addEvent = function (o, type, fn) { if (!o._events) o._events = {}; var queue = o._events[type]; if (!queue) { o._events[type] = [fn]; if (!o._events._callback) o._events._callback = function (e) { Event._callListeners(e, o) }; o.attachEvent("on" + type, o._events._callback); } else if (Event._fnIndex(o, type, fn) == -1) queue.push(fn); else return; Event._mem.push([o, type, fn]); }; var removeEvent = function (o, type, fn) { var i = Event._fnIndex(o, type, fn); if (i < 0) return; var queue = o._events[type]; if (queue.calling) { delete queue[i]; if (queue.removeListeners) queue.removeListeners.push(i); else queue.removeListeners = [i]; } else if (queue.length == 1) Event._detach(o, type); else queue.splice(i, 1); }; var Event = { AT_TARGET: 2, BUBBLING_PHASE: 3, stopPropagation: function () { this.cancelBubble = true }, preventDefault: function () { this.returnValue = false }, _mem: [], _callListeners: function (e, o) { e.stopPropagation = this.stopPropagation; e.preventDefault = this.preventDefault; e.currentTarget = o; e.target = e.srcElement; e.eventPhase = e.currentTarget == e.target ? this.AT_TARGET : this.BUBBLING_PHASE; switch (e.type) { case "mouseover": e.relatedTarget = e.fromElement; break; case "mouseout": e.relatedTarget = e.toElement; } var queue = o._events[e.type]; queue.calling = true; for (var i = 0, l = queue.length; i < l; i++) if (queue[i]) if ("handleEvent" in queue[i]) queue[i].handleEvent(e); else queue[i].call(o,e); queue.calling = null; if (!queue.removeListeners) return; if (queue.length == queue.removeListeners.length) { this._detach(o, e.type); return; } queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b}); var i = queue.removeListeners.length; while (i--) queue.splice(queue.removeListeners[i], 1); if (queue.length == 0) this._detach(o, e.type); else queue.removeListeners = null; }, _detach: function (o, type) { o.detachEvent("on" + type, o._events._callback); delete o._events[type]; }, _fnIndex: function (o, type, fn) { var queue = o._events[type]; if (queue) for (var i = 0, l = queue.length; i < l; i++) if (queue[i] == fn) return i; return -1; }, _cleanup: function () { for (var m, i = 0; m = Event._mem[i]; i++) if (m[1] != "unload" || m[2] == Event._cleanup) removeEvent(m[0], m[1], m[2]); } }; addEvent(window, "unload", Event._cleanup); } @*/
后来,又发现Dean Edwards也修正了IE事件顺序错乱问题
// addEvent/removeEvent written by Dean Edwards, 2005 // with input from Tino Zijdel // http://dean.edwards.name/weblog/2005/10/add-event/ function addEvent(element, type, handler) { if (!handler.$$guid) handler.$$guid = addEvent.guid++; if (!element.events) element.events = {}; var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {}; if (element["on" + type]) { handlers[0] = element["on" + type]; } } handlers[handler.$$guid] = handler; element["on" + type] = handleEvent; }; addEvent.guid = 1; function removeEvent(element, type, handler) { if (element.events && element.events[type]) { delete element.events[type][handler.$$guid]; } }; function handleEvent(event) { var returnValue = true; event = event || fixEvent(window.event); var handlers = this.events[event.type]; for (var i in handlers) { this.$$handleEvent = handlers[i]; if (this.$$handleEvent(event) === false) { returnValue = false; } } return returnValue; }; function fixEvent(event) { event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; return event; }; fixEvent.preventDefault = function() { this.returnValue = false; }; fixEvent.stopPropagation = function() { this.cancelBubble = true; };
function addEvent(element, type, handler) { if (!handler.$$guid) handler.$$guid = addEvent.guid++; if (!element.events) element.events = {};//一个巨大的哈希, var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {};//哈希的每一个键都是哈希 if (element["on" + type]) { handlers[0] = element["on" + type]; } } handlers[handler.$$guid] = handler; element["on" + type] = function(event) { var returnValue = true; event = event || window.event; var handlers = this.events[event.type]; for (var i in handlers) { this.$$handleEvent = handlers[i]; if (this.$$handleEvent(event) === false) { returnValue = false; } } return returnValue; }; }; addEvent.guid = 1;
相关文章推荐
- javascript attachEvent绑定多个事件执行顺序问题
- javascript attachEvent绑定多个事件执行顺序问题
- attachEvent绑定多个事件执行顺序问题
- JavaScript-父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序
- ASP.NET页面执行顺序(第二个LoadViewState事件可以解释我新浪博客中的“HiddenField隐藏域的值改变时onvaluechanged的事件触发问题”一文的问题)
- JS一起学01:css复习、js基础知识、事件、参数、函数、网页换肤、if判断、className问题、浏览器执行顺序
- jquery 绑定点击事件 多次执行问题
- JavaScript的执行顺序及onload的事件的一些问题
- IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素
- ASP.net验证控件详解和按钮点击事件后验证控件的执行顺序问题以及在确认密码框为空,CompareValidator认为是合法的问题的解决方案
- 看懂此文,不再困惑于javascript中的事件绑定、事件冒泡、事件捕获和事件执行顺序
- 同一事件绑定不同的处理方法、执行顺序有所不同
- ASPX防止重复执行Page_Load以及事件绑定的问题
- js前端--解决非IE浏览器事件绑定的一些问题
- for循环内绑定事件的问题(立即执行与延迟执行)。
- jQuery $(function(){})和onload事件执行顺序问题
- Jquery前端之 事件绑定(二) 解决事件的删除,事件的无序执行的问题,有个小例子
- 解决事件多次绑定,执行多次问题
- 鼠标滚动一次window.onscroll事件的函数在firfox与Ie中执行的次数不同问题的处理s
- 鼠标滚动事件onscroll在firefox/chrome/Ie中执行次数的问题处理