这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
第三篇,继续总结事件对象 先看看监听鼠标滚轮事件能帮我们做什么
[Ctrl+A 全选 注: 如需引入外部 Js 需刷新才能执行]
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- <html>
- <head>
- <title>Mouse Wheel Data</title>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <style>
- .slider
- {
- width:50px;
- height:180px;
- background:#eee;
- padding:10px 0;
- cursor:n-resize;
- }
- .slider-slot
- {
- width:16px;
- margin:0 auto;
- height:180px;
- background:#eee;
- border:1px solid gray;
- border-color:#999 white white #999;
- position:relative;
- }
- .slider-trigger
- {
- width:14px;
- height:18px;
- font:1px/0 arial;
- border:1px solid gray;
- border-color:white #999 #999 white;
- background:#ccc;
- position:absolute;
- }
- .slider-trigger b
- {
- display:block;
- margin:1px 3px;
- border-top:1px solid #999;
- border-bottom:1px solid white;
- }
- </style>
- </head>
- <body>
- <h2>文本框增加/减少值</h2>
- <div><input type="text" id="txt" value="1440" />文本框获得焦点后滚动鼠标滚轮</div>
- <h2>鼠标滚动缩放图片</h2>
- <div><img class="img-responsive" src="http://img.phperz.com/data/img/20170322_4/1490191055_8367.jpg" width="300" data-src="" ></div>
- <h2>鼠标滚动控制滑块移动</h2>
- <div>
- <div>
- <div>
- <strong></strong>
- <strong></strong>
- <strong></strong>
- <strong></strong>
- <strong></strong>
- </div>
- </div>
- </div>
- </body>
- <script>
- var $ = function(i)
- {
- return document.getElementById( i );
- }
- //取得滚动值
- function getWheelValue( e )
- {
- e = e||event;
- return ( e.wheelDelta ? e.wheelDelta/120 : -( e.detail%3 == 0 ? e.detail/3 : e.detail ) ) ;
- }
- function stopEvent(e)
- {
- e = e||event;
- if( e.preventDefault )e.preventDefault();
- e.returnValue = false;
- }
- //绑定事件,这里对mousewheel做了判断,注册时统一使用mousewheel
- function addEvent( obj,type,fn )
- {
- var isFirefox = typeof document.body.style.MozUserSelect != 'undefined';
- if( obj.addEventListener )
- obj.addEventListener( isFirefox ? 'DOMMouseScroll' : type,fn,false );
- else
- obj.attachEvent( 'on'+type,fn );
- return fn;
- }
- //移除事件,这里对mousewheel做了兼容,移除时统一使用mousewheel
- function delEvent( obj,type,fn )
- {
- var isFirefox = typeof document.body.style.MozUserSelect != 'undefined';
- if( obj.removeEventListener )
- obj.removeEventListener( isFirefox ? 'DOMMouseScroll' : type,fn,false );
- else
- obj.detachEvent( 'on'+type,fn );
- }
- /*限制范围函数,
- 参数是三个数字,如果num 大于 max, 则返回max, 如果小于min,则返回min,如果在max和min之间,则返回num
- */
- function range( num, max,min )
- {
- return Math.min( max, Math.max( num,min ) );
- }
- /* ------------ */
- /* <h2>文本框增加/减少值</h2> */
- $( 'txt' ).onfocus = function()
- {
- //保存txt自己的引用
- var me = this,
- //onfocus之后注册滚轮事件
- handler = addEvent( me,'mousewheel',function(e)
- {
- stopEvent( e );
- var delta = getWheelValue(e);
- /*
- +me.value 将me.value转换成数字,
- 然后使用isNaN检查转换后的数字是否为NaN
- 如果是,重新赋值me.value=0;
- */
- if( isNaN( +me.value ) ) me.value = 0;
- //递增(或递减)
- me.value = +me.value + delta;
- //选中me里的文字
- me.select();
- });
- //失去焦点时,把mousewheel事件移除,重置window.onblur和handler引用为null
- this.onblur = function()
- {
- //移除掉mousewheel事件
- delEvent( me,'mousewheel',handler );
- window.onblur = handler = null;
- }
- //为了防止浏览器失焦后,文本框重复触发focus,在onblur时,让文本框同时失焦
- window.onblur = function()
- {
- me.blur();
- //把自己清理掉
- this.onblur = null;
- }
- }
- /* <h2>鼠标滚动缩放图片</h2> */
- addEvent( $('img'),'mousewheel',function(e)
- {
- stopEvent( e );
- var delta = getWheelValue(e);
- //每次递增(或递减)10px,使用了范围限制,保证图片不会过大过小
- var img = $('img'); //没有修复ie的this指向,所以这里只好重新获取img
- img.style.width = range( img.offsetWidth + ( delta * 10 ),550,100) + 'px';
- return false;
- });
- /* <h2>鼠标滚动控制滑块移动</h2> */
- addEvent( $('slider'), 'mousewheel',function(e)
- {
- stopEvent( e );
- var delta = getWheelValue(e),
- tar = $('sliderTrigger');
- //杯具的反转,因为tar.offsetTop 越大,滑块就越往下,所以delta又需要反转回来,向上是负的,向下是正的,所以乘以-1
- tar.style.top = range( tar.offsetTop + ( -1 * delta * 10 ),160,0 ) + 'px';
- });
- </script></html>
先来看看各个浏览器的兼容情况
IE 6,7,8
注册事件使用 onmousewheel
取得滚动的值使用 event.wheelDelta
滚动步长 120
向下是负值,向上是正值
当鼠标在一个同一个坐标,并且滚轮不间断滚动时,wheelDelta 会按步长递增
(比如 -240 -360 )
Firefox 3.5
注册事件有两个 MozMousePixelScroll,DOMMouseScroll, 但是它们不能使用 element.onDOMMouseScroll 方式注册,必须使用 addEventLinstener 来监听事件
Firefox 没有 event.wheelDelta, 它使用 event.detail 来获取滚动的信息 (Firefox 这点做的很奇怪)
event.detail 本身是用来记录一个事件在原地 (鼠标坐标不发生变化的情况下) 执行了多少次的信息
而在 DOMMouseScroll 事件发生的时候,它的值通常是 3 和 -3
但是它的取值和 IE 正好相反, 向上是负, 向下是正 (这个问题在代码中需要做统一)
为什么说它的值通常是 3 和 - 3 呢,因为当你按住 ctrl ,alt, shift 之后,再滑动鼠标滚轮,detail 的值就会成为 1 和 - 1
而按住别的键,则正值有时还会变成 6
总之在我看来是有点乱糟糟,
MozMousePixelScroll 据 Mozilla 说,是几乎跟 DOMMouseScroll 一样的事件,只不过更精确(到像素)
但是这个事件的 detail 值返回的非常奇怪,默认是 51 和 - 51, 按住 ctrl ,alt, shift 变成了 +- 17. @_@,所以它被华丽的无视了,我们不打算使用它
Chrome 和 IE 保持一致,但是它考虑到了横向鼠标滚轮设备的情况,所以增加了两个鼠标来分别获取值
事件 onmousewheel
wheelDelta {number}
wheelDeltaX {number}
wheelDeltaY {number}
这次 Opera 又是集大成者,既有 detail 取值也一样是 3,-3, 又有 wheelDelta, 不过表现上倒是很一致
事件 onmousewheel
detail = {number}
wheelDelta = {number}
本来我们应该从 Firefox 支持的 event.detail 或者 IE 等支持的 event.wheelDelta 的取值中,选择一个,然后把另一个通过计算做成统一的,
但是实际上我们只能通过这些值知道 是向上滚 还是向下滚,
所以为了方便,我们两个都不取,通过计算把他们统一成 +1 和 -1.(这样做也是为了实际应用中的运算方便);
对于 IE,Chrome 来说,直接除以 120 就可以搞定
Opera 同时支持 wheelDelta 和 detail , 但是 detail 没有 wheelDelta 同一位置递增的能力,所以
我们首先优先判断 wheelDelta 是否存在,如果存在,就使用 wheelDelta, 如果不存在再使用 detail
由于 firefox 的键盘干扰,我们还需要对 detail 做一些过滤
首先用这个值跟 3 做取模运算 value % 3
说它是 3 的倍数,那么返回值是 0,我们就用 value 除以 3 后返回 (保证返回的值是 + 1 -1)
如果返回值不是 0,那说明这个值不是 1 就是 - 1,那就直接返回这个值
最后,由于 Firefox 返回值的规则是向上是负 向下是正,与平时的习惯不同,我们要将正负反转过来,方法也很简单,计算结果前面加一个负号就可以搞定
话说回来,对滚轮事件的支持情况 firefox 真是有点闷.
好了,分析了一大堆,其实代码就几句:
- function getWheelValue( e )
- {
- e = e||event;
- return ( e.wheelDelta ? e.wheelDelta/120 : -( e.detail%3 == 0 ? e.detail : e.detail/3 ) );
- }
最后说说未来的滚轮事件和 API
在 DOM3 Event 中
滚轮事件变得更为复杂(也支持更多的东西)
注册的事件并没有变,依然叫 mousewheel
专门增加了两枚滚轮事件对象
MouseWheelEvent
WheelEvents
而且支持了 x,y,z 三个轴向的滚轮值 (真复杂>_< )
感兴趣可以瞧瞧这里
来源: http://www.phperz.com/article/17/0705/284805.html