前面跟网友讨论到了JS的事件队列 ,对这个有了一些理解,事件队列我认为就是把一些不按顺序执行的事件放到队列里面,然后按照自己制定的顺序去执行,那么什么情况下会用到这个呢?我首先想到的是动画,动画是会执行一系列的操作,一连串的方法,但是后面讨论,这也只能算是函数或方法队列,事件队列应该是关联到element的触发和事件绑定。
那么经过网友的讨论,找到这么一个例子,那就是element的事件监听,除了直接用框架(jquery dojo yui等)外,一般的监听都会是这样
if(window.addEventListener){ ...... }else if(window.attachEvent){//IE8或更低 ...... }
但是这里 window.attachEvent 的实现顺序跟绑定的的顺序刚好相反
var obj = document.getElementById('test'); obj.attachEvent('onclick',function{ alert(1); }); obj.attachEvent('onclick',function{ alert(2); });
这样的例子在IE8或更低的IE版本下运行,会先是弹出 2 再弹出 1 ,至于为什么,那要去问微软了。
如果要做一个兼容的事件监听,那么就会用到队列了,队列就可以很好的控制事件的执行顺序,于是写了这么一个例子(代码很挫......)
<!doctype html> <html> <head> <meta charset="utf-8"> <title>js事件队列</title> </head> <body> <a href="javascript:;" id="tobj">点击我1</a> <a href="javascript:;" id="yobj">点击我2</a> <script> var tobj = document.getElementById('tobj') ,ton ; if(window.addEventListener){ ton = function(type,cb){ tobj.addEventListener(type,cb,false); } }else if(window.attachEvent){//IE8或更低 ton = function(type,cb){ tobj.attachEvent('on'+type,cb); } } ton('click',function(){ console.log(1); }); ton('click',function(){ console.log(2); }); /* 最后等到的结果是: IE8以及IE8以下:2 1 IE9或更高: 1 2 FF或chrome: 1 2 这种情况下 为了保持能够按照 顺序执行 所以要采用队列解决 */ //简单队列对象 var aqueue = function(){ this.list = []; this.num = 0;//执行次数记录 防止多次监听造成的多次执行 }; aqueue.prototype = { add:function(fn){ this.list.push(fn); } ,size:function(){ return this.list.length; } ,done:function(elem){ var _self = this ,len = _self.size() ,i=0 ; if(_self.num===len){//如果执行次数等于事件数量 _self.num=0;//初始化执行次数 }else{ for(;i<len;i++){ _self.list[i].call(elem); _self.num++; } } } }; var aq = new aqueue(); var yobj = document.getElementById('yobj') ,yon ; if(window.addEventListener){ yon = function(type,cb){ aq.add(cb);//把事件加入队列 yobj.addEventListener(type,function(){ aq.done(yobj); },false); } }else if(window.attachEvent){//IE8或更低 yon = function(type,cb){ aq.add(cb);//把事件加入队列 yobj.attachEvent('on'+type,function(){ aq.done(yobj); }); } } yon('click',function(){ console.log(1); }); yon('click',function(){ console.log(2); }); </script> </body> </html>
这里用的是console.log 输出结果,只有在控制台才能看到,另外要注意的是用 window.attachEvent 监听,方法里面的 this 并不是指向监听对象,而是指向window。