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>
</style>
</head>
<body>
	<h2>文本框增加/减少值</h2>
	<div>
		<input type="text" id="txt" value="1440" /><span id="warn">文本框获得焦点后滚动鼠标滚轮</span>
	</div>
	<h2>鼠标滚动缩放图片</h2>
	<div>
		<img src="http://files.jb51.net/upload/201005/20100531231516458.jpg"
			id="img" width="300" style="cursor: -moz-zoom-in" title="鼠标滚动 缩放大小"
			/ alt="" />
	</div>
	<h2>鼠标滚动控制滑块移动</h2>
	<div class="slider" id="slider">
		<div class="slider-slot">
			<div class="slider-trigger" id="sliderTrigger">
				<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.w3.org/TR/DOM-Level-3-Events/#events-mousewheelevents
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值