淺談滑鼠滾輪事件,淺談滑鼠滾輪
現在的網頁設計越來越高大上,效果越來越炫酷斃。一些瀏覽器的預設東西都被紛紛嫌棄,取而代之的是各種酷炫拽的類比組件。就好像之前說過的視差滾動,又好像各種小清新的類比捲軸,都有共同的事件:滾輪事件。
正如大家所知道的那樣,jquery架構預設是不支援滑鼠中輪滾輪事件的。要實現不同瀏覽器之間的滾輪事件,我們不能不說一下這個js組件了:jquery.mousewheel.js。
什麼都不說,先上源碼:
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh) * Licensed under the MIT License (LICENSE.txt). * * Version: 3.1.11 * * Requires: jQuery 1.2.2+ */(function (factory) { if ( typeof define === 'function' && define.amd ) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS style for Browserify module.exports = factory; } else { // Browser globals factory(jQuery); }}(function ($) { var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], slice = Array.prototype.slice, nullLowestDeltaTimeout, lowestDelta; if ( $.event.fixHooks ) { for ( var i = toFix.length; i; ) { $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; } } var special = $.event.special.mousewheel = { version: '3.1.11', setup: function() { if ( this.addEventListener ) { for ( var i = toBind.length; i; ) { this.addEventListener( toBind[--i], handler, false ); } } else { this.onmousewheel = handler; } // Store the line height and page height for this particular element $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); }, teardown: function() { if ( this.removeEventListener ) { for ( var i = toBind.length; i; ) { this.removeEventListener( toBind[--i], handler, false ); } } else { this.onmousewheel = null; } // Clean up the data we added to the element $.removeData(this, 'mousewheel-line-height'); $.removeData(this, 'mousewheel-page-height'); }, getLineHeight: function(elem) { var $parent = $(elem)['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); if (!$parent.length) { $parent = $('body'); } return parseInt($parent.css('fontSize'), 10); }, getPageHeight: function(elem) { return $(elem).height(); }, settings: { adjustOldDeltas: true, // see shouldAdjustOldDeltas() below normalizeOffset: true // calls getBoundingClientRect for each event } }; $.fn.extend({ mousewheel: function(fn) { return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); }, unmousewheel: function(fn) { return this.unbind('mousewheel', fn); } }); function handler(event) { var orgEvent = event || window.event, args = slice.call(arguments, 1), delta = 0, deltaX = 0, deltaY = 0, absDelta = 0, offsetX = 0, offsetY = 0; event = $.event.fix(orgEvent); event.type = 'mousewheel'; // Old school scrollwheel delta if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } // Firefox < 17 horizontal scrolling related to DOMMouseScroll event if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { deltaX = deltaY * -1; deltaY = 0; } // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy delta = deltaY === 0 ? deltaX : deltaY; // New school wheel delta (wheel event) if ( 'deltaY' in orgEvent ) { deltaY = orgEvent.deltaY * -1; delta = deltaY; } if ( 'deltaX' in orgEvent ) { deltaX = orgEvent.deltaX; if ( deltaY === 0 ) { delta = deltaX * -1; } } // No change actually happened, no reason to go any further if ( deltaY === 0 && deltaX === 0 ) { return; } // Need to convert lines and pages to pixels if we aren't already in pixels // There are three delta modes: // * deltaMode 0 is by pixels, nothing to do // * deltaMode 1 is by lines // * deltaMode 2 is by pages if ( orgEvent.deltaMode === 1 ) { var lineHeight = $.data(this, 'mousewheel-line-height'); delta *= lineHeight; deltaY *= lineHeight; deltaX *= lineHeight; } else if ( orgEvent.deltaMode === 2 ) { var pageHeight = $.data(this, 'mousewheel-page-height'); delta *= pageHeight; deltaY *= pageHeight; deltaX *= pageHeight; } // Store lowest absolute delta to normalize the delta values absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; // Adjust older deltas if necessary if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { lowestDelta /= 40; } } // Adjust older deltas if necessary if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { // Divide all the things by 40! delta /= 40; deltaX /= 40; deltaY /= 40; } // Get a whole, normalized value for the deltas delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); // Normalise offsetX and offsetY properties if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { var boundingRect = this.getBoundingClientRect(); offsetX = event.clientX - boundingRect.left; offsetY = event.clientY - boundingRect.top; } // Add information to the event object event.deltaX = deltaX; event.deltaY = deltaY; event.deltaFactor = lowestDelta; event.offsetX = offsetX; event.offsetY = offsetY; // Go ahead and set deltaMode to 0 since we converted to pixels // Although this is a little odd since we overwrite the deltaX/Y // properties with normalized deltas. event.deltaMode = 0; // Add event and delta to the front of the arguments args.unshift(event, delta, deltaX, deltaY); // Clearout lowestDelta after sometime to better // handle multiple device types that give different // a different lowestDelta // Ex: trackpad = 3 and mouse wheel = 120 if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); return ($.event.dispatch || $.event.handle).apply(this, args); } function nullLowestDelta() { lowestDelta = null; } function shouldAdjustOldDeltas(orgEvent, absDelta) { // If this is an older event and the delta is divisable by 120, // then we are assuming that the browser is treating this as an // older mouse wheel event and that we should divide the deltas // by 40 to try and get a more usable deltaFactor. // Side note, this actually impacts the reported scroll distance // in older browsers and can cause scrolling to be slower than native. // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; }}));
js外掛程式裡面主要的2個函數就是mousewheel和unmousewheel。
調用方式也是多種多樣,
例如你可以這樣:
$('.demo').mousewheel(function(){//to do something}); $('.demo').bind('mousewheel', function(){//to do something});
下面來說說它的參數。
mousewheel事件的參數除了第一個參數event外,還會接收第二個參數delta。通過參數delta可以擷取滑鼠滾輪的方向和速度。如果delta的值是負的,那麼滾輪就是向下滾動,正的就是向上。
舉個例子:
var gao=document.documentElement.clientHeight,h,wflag=true,fh=0,uph=0,yundong=true;$('.mod-step').css('height',gao); $('.mod-step').bind('mousewheel', function(event, delta) { if(yundong==true){yundong=false;var index=parseInt($(this).index('.mod-step'))+1;h=gao*index;if(delta < 0){ //如果是向下滾動就幹什麼事情//to do something}else{ //如果是向上滾動就幹什麼事情 //to do something }
ps:看看參數如何調用就行,其他代碼的細節可以忽略。
接下來看看不同瀏覽器返回的不同的值。
先看Google瀏覽器的:向下滾動時,
然後是Firefox的,向下滾動時,
然後是ie11的,向下滾動:
然後是ie9的,向下滾動:
接下來就是ie8,向下滾動的:
總結:各種瀏覽器返回的數值基本都不一樣。所以如果要用具體數字判斷,還是不科學的,但是用是否大於0,還是靠譜的。
當中的差異,如果有興趣的可以去張鑫旭的部落格看看。附上網址:http://www.zhangxinxu.com/wordpress/2013/04/js-mousewheel-dommousescroll-event/
滾輪事件的各種運用,我就不多說了,提供幾個demo給大家去看看,真心好用。
http://joelb.me/scrollpath/
http://manos.malihu.gr/jquery-custom-content-scroller/
http://noraesae.github.io/perfect-scrollbar/
總結:雖然不是什麼大外掛程式,但是填補了jQuery沒有滾輪事件的缺陷,簡單實用。
Author: Alone
Antroduction: 進階前端開發工程師
Sign: 人生沒有失敗,只有沒到的成功。
淺析怎屏蔽C#滑鼠滾輪相關事件
C#滑鼠滾輪主要是針對滑鼠上的滾輪滾動中,改變值的問題。通過這一代碼能解決這個問題,其中需要用到IMessageFilter 成員。C#滑鼠滾輪也是滑鼠控制的重要組成部分。
JS怎判斷滑鼠滾輪事件分析
我們都見到過這些效果,用滑鼠滾輪實現某個表單內的數字增加減少操作,或者滾輪控制某個按鈕的左右,上下滾動。這些都是通過js對滑鼠滾輪的事件監聽來實現的。今天這裡介紹的是一點簡單的js對於滑鼠滾輪事件的監聽。先分析原理:我們是通過判斷滑鼠滾動的擷取一個值,然後根據這個值判斷滾動的方向。然而不同瀏覽器有不同的擷取方法,所以要分瀏覽器寫方法。不同瀏覽器不同的事件首先,不同的瀏覽器有不同的滾輪事件。主要是有兩種,onmousewheel(firefox不支援)和DOMMouseScroll(只有firefox支援),關於這兩個事件這裡不做詳述,想要瞭解的朋友請先去瞭解滑鼠滾輪(mousewheel)和DOMMouseScroll事件。過程中需要添加事件監聽:相容firefox採用addEventListener監聽。js返回數值判斷滾輪上下判斷滾輪向上或向下在瀏覽器中也要考慮相容性(IE、Opera、Safari、Firefox、Chrome)中Firefox 使用detail,其餘四類使用wheelDelta;兩者只在取值上也是不一致,但是含義一致,detail與wheelDelta只各取兩個 值,detail只取±3,wheelDelta只取±120,其中正數表示為向上,負數表示向下。 具體的代碼如下所示:<label for=wheelDelta滾動值:</label(IE/Opera)<input type=text id=wheelDelta/<label for=detail滾動值:(Firefox)</label<input type=text id=detail/<script type=text/javascriptvar scrollFunc=function(e){e = e || window.event;var t1=document.getElementById(wheelDelta);var t2=document.getElementById(detail);if(e.wheelDelta){//IE/Opera/Chromet1.value=e.wheelDelta;}else if(e.detail){//Firefoxt2.value=e.detail;}}/*監聽事件*/