javascript兼容性添加清除滚轮事件
前端难
——小指夜哭
一入前端无底洞,从此身体被掏空。
工具架构不相通,样式脚本难兼容。
前端难,前端难,多歧路,脑仁痛。
安得世间本如法,堪破迷蒙见霓虹。
什么鬼?看Javascript滚轮事件就知道了,各种兼容性直接把你上个月吃的的隔夜饭都恶心吐了~
普通事件对象传递
浏览器 | IE6/7/8 | FF | IE9/Opera/Safari/Chrome |
传递方法 | 支持通过window.event获取事件对象。attachEvent方式添加事件时也支持通过事件对象作为绑定函数的第一个参数传入 | 任何时候只支持事件对象作为绑定函数第一个参数传入 | 任何时候同时支持两种方式 |
普通事件采用方法绑定和解绑方法
绑定时,推荐绑定普通函数,不要绑定匿名函数,否则无法解绑;
IE中绑定事件this为window,事件有on前缀,同一个事件绑定的多个函数,后绑定的先执行;
其余浏览器this为绑定对象,事件不需要on前缀,同一个事件绑定的多个函数,按绑定顺序执行;
addEventListener中userCapture参数默认为false,表示在冒泡阶段绑定函数,true表示在捕获阶段绑定函数。
浏览器 | IE | Chrome | FF |
事件绑定方法 | element.attachEvent(event, function) | element.addEventListener(event, function, useCapture) | element.addEventListener(event, function, useCapture) |
事件解绑方法 | element.detachEvent(event, function) | element.removeEventListener(event, function, useCapture) | element.removeEventListener(event, function, useCapture) |
滚轮事件
浏览器 | IE | Chrome | FF |
滚动事件 | mousewheel(普通事件) | mousewheel(普通事件) | DOMMouseScroll(DOM事件,只能通过事件绑定方法绑定事件) |
滚动事件参数属性 | wheelDelta | wheelDelta | detail |
参数属性和上下关系,滚轮滚一格出现一个相应的数 | 向上滚:120 向下滚:-120 | 向上滚:120 向下滚:-120 | 向上滚:-3 向下滚:3 |
哭了吗,看下去吧,好东西在下面哦~
滚轮事件获取兼容实现方法
以下例子兼容实现了
添加绑定事件和清除绑定事件的方法:
事件函数可为匿名函数,尝试在相同事件绑定相同函数将直接忽略,自动阻止了事件默认行为和事件冒泡。
添加绑定滚轮事件和清除绑定滚轮事件:
将向下事件函数和向上事件函数分离,利用兼容函数将其再次合并。
个人认为多个向上向下滚轮事件函数没必要,因此本例仅实现了绑定单一向上向下函数,若需要可自行添加。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>迷津渡口-javascript兼容性添加清除滚轮事件分享</title> <script> window.onload = function() { // 获取DOM对象 var oBtn1=document.getElementById('btn1'); var oBtn2=document.getElementById('btn2'); var oDiv = document.getElementById('div1'); // 点击oBtn1绑定oDiv的滚轮事件 addEvent(oBtn1,'click',function(){addMouseWheel(oDiv, fnDown, fnUp);}); // 点击oBtn2清除oDiv的滚轮事件 addEvent(oBtn2,'click',function(){removeMouseWheel(oDiv);}); }; // 兼容性添加事件 function addEvent(obj, sEvent, fn) { // 如果事件函数未被绑定过 if (!obj['b' + sEvent + fn]) { // 利用独一无二的属性名保存绑定的函数 // 同时利用call解决this问题,解决event兼容性,组织默认事件行为和事件冒泡 obj['e' + sEvent + fn] = function(evt) {fn.call(obj,evt);if (evt.preventDefault) evt.preventDefault();if (evt.stopPropagation) evt.stopPropagation();return false;}; if (obj.attachEvent) { obj.attachEvent('on' + sEvent, obj['e' + sEvent + fn]); } else { obj.addEventListener(sEvent, obj['e' + sEvent + fn], false); } obj['b' + sEvent + fn] = true; } } // 兼容性清除事件 function removeEvent(obj, sEvent, fn) { if (obj['b' + sEvent + fn]) { if (obj.detachEvent) { obj.detachEvent('on' + sEvent, obj['e' + sEvent + fn]); } else { obj.removeEventListener(sEvent, obj['e' + sEvent + fn], false); } delete(obj['b' + sEvent + fn]); delete(obj['e' + sEvent + fn]); } } // 兼容性添加滚轮事件 // 为方便将向上事件函数和向下事件函数分开传递 // 个人认为没必要多个,因此没做多个,有需要也可以自行添加 function addMouseWheel(obj, fnDown, fnUp) { // 获取向下和向上滚动的次数,易知相减就是滚动的总数 obj.scrollDownNum=0; obj.scrollUpNum=0; // 将向下事件和向上事件合并绑定到滚轮事件里 // 利用call保证this的一致性,传递evt保证事件兼容性 obj.mousewheelfunction = function(evt) { if (isMouseWheelDown(evt)) { fnDown.call(obj,evt); } else { fnUp.call(obj,evt); } }; addEvent(obj, 'mousewheel', obj.mousewheelfunction); addEvent(obj, 'DOMMouseScroll', obj.mousewheelfunction); } // 兼容性清除滚轮事件 // 这里仅仅需清除一个属性函数,没必要传其他参数 function removeMouseWheel(obj) { if (obj.mousewheelfunction) { removeEvent(obj, 'mousewheel', obj.mousewheelfunction); removeEvent(obj, 'DOMMouseScroll', obj.mousewheelfunction); delete(obj.mousewheelfunction); } } // 判断滚轮是否向下滚动一格 function isMouseWheelDown(evt) { return evt.wheelDelta ? evt.wheelDelta < 0 : evt.detail > 0; } // 每向下滚动一格,执行一次本函数 function fnDown(evt) { console.log('向下滚动事件的目标ID为:'+evt.target.id+',向下滚动次数为:'+ ++this.scrollDownNum); if (parseInt(this.style.height) < 1800)this.style.height=parseInt(this.style.height)+10+'px'; } // 每向上滚动一格,执行一次本函数 function fnUp(evt) { console.log('\t向上滚动事件的目标ID为:'+evt.target.id+',向上滚动次数为:'+ ++this.scrollUpNum); if (parseInt(this.style.height) > 50)this.style.height=parseInt(this.style.height)-10+'px'; } </script> </head> <body style="height:2000px;"> <button id="btn1">绑定滚轮事件</button><button id="btn2">清除滚轮事件</button> <div id='div1' style="margin-top:20px;width:200px;height:200px;background:red;"></div> </body> </html>
小指才疏学浅,有任何疏漏之处,欢迎不吝赐教~
点赞3
支持一下