@livelybone/mouse-wheel
Version:
A module for bind mouse-wheel event. typescript supported
154 lines (133 loc) • 4.48 kB
JavaScript
/**
* Bundle of @livelybone/mouse-wheel
* Generated: 2020-05-16
* Version: 4.2.1
* License: MIT
* Author: 2631541504@qq.com
*/
var prefix = '';
var $addEventListener = 'addEventListener';
var $removeEventListener = 'removeEventListener';
var support = 'wheel';
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
// detect event model
if ('addEventListener' in window) {
$addEventListener = 'addEventListener';
$removeEventListener = 'removeEventListener';
} else {
$addEventListener = 'attachEvent';
$removeEventListener = 'detachEvent';
prefix = 'on';
} // detect available wheel event
if ('onwheel' in document.createElement('div')) {
// "Wheel" is supported by most higher versions of browsers
// 各个厂商的高版本浏览器都支持"wheel"
support = 'wheel';
} else if (window.onmousewheel !== undefined) {
// Webkit and IE always support "mousewheel"
// Webkit 和 IE一定支持"mousewheel"
support = 'mousewheel';
} else {
// Low version of firefox
// 低版本firefox
support = 'DOMMouseScroll';
}
}
function dealOriginalEvent(ev) {
var originalEvent = ev || window.event; // create a normalized event object
var event = {
// keep a ref to the original event object
originalEvent: originalEvent,
timeStamp: originalEvent.timeStamp,
target: originalEvent.target || originalEvent.srcElement,
type: 'wheel',
deltaMode: originalEvent.type === 'MozMousePixelScroll' ? 0 : 1,
deltaX: 0,
deltaY: 0,
deltaZ: 0,
preventDefault: function preventDefault() {
if (originalEvent.preventDefault) originalEvent.preventDefault();else originalEvent.returnValue = false;
}
}; // calculate deltaY (and deltaX) according to the event
if (support === 'mousewheel') {
event.deltaY = -1 / 40 * originalEvent.wheelDelta;
if (originalEvent.wheelDeltaX) {
// Webkit also support wheelDeltaX
event.deltaX = -1 / 40 * originalEvent.wheelDeltaX;
}
} else {
event.deltaY = originalEvent.detail;
}
return event;
}
function getExHeight(elem) {
var el = elem instanceof Window ? document.documentElement : elem;
var fontSize = window.getComputedStyle(el).fontSize || '16px';
return parseInt(fontSize, 10);
}
function $addWheelListener(element, eventName, listener) {
var $options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var options = {
debounceTime: $options.debounceTime || 0,
interval: $options.interval || 500,
useCapture: $options.useCapture || false
};
var timer;
var lastTime = 0;
function $listener(ev) {
var e = support === 'wheel' ? ev : dealOriginalEvent(ev);
var timeDelta = e.timeStamp - lastTime;
var type = 'wheelMove';
if (timeDelta < options.debounceTime) return;
if (timeDelta > options.interval) type = 'wheelStart'; // deltaMode: https://developer.mozilla.org/zh-CN/docs/Web/API/WheelEvent/deltaMode
var scale = 1;
if (e.deltaMode === 1) {
scale = getExHeight(element);
} else if (e.deltaMode === 2) {
scale = window.innerHeight;
}
var dTime = type !== 'wheelStart' ? timeDelta : 0;
listener({
dx: e.deltaX * scale || 0,
dy: e.deltaY * scale || 0,
dz: e.deltaZ * scale || 0,
dTime: dTime,
originalEvent: e,
type: type
});
lastTime = e.timeStamp;
clearTimeout(timer);
timer = setTimeout(function () {
listener({
dx: 0,
dy: 0,
dz: 0,
dTime: dTime + options.interval,
originalEvent: {
timeStamp: e.timeStamp + options.interval
},
type: 'wheelEnd'
});
}, options.interval);
}
var addListener = element[$addEventListener];
addListener(prefix + eventName, $listener, options.useCapture);
return function () {
var removeListener = element[$removeEventListener];
removeListener(prefix + eventName, $listener, options.useCapture);
};
}
var bind = function bind(element, listener, options) {
/* eslint-disable no-param-reassign */
if (typeof element === 'function') {
options = listener;
listener = element;
element = window;
}
if (support === 'DOMMouseScroll') {
// handle MozMousePixelScroll in older Firefox
return $addWheelListener(element, 'MozMousePixelScroll', listener, options);
}
return $addWheelListener(element, support, listener, options);
};
export { bind };