mouse-wheel.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. 'use strict';
  2. var instances = require('../instances')
  3. , updateGeometry = require('../update-geometry')
  4. , updateScroll = require('../update-scroll');
  5. function bindMouseWheelHandler(element, i) {
  6. var shouldPrevent = false;
  7. function shouldPreventDefault(deltaX, deltaY) {
  8. var scrollTop = element.scrollTop;
  9. if (deltaX === 0) {
  10. if (!i.scrollbarYActive) {
  11. return false;
  12. }
  13. if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
  14. return !i.settings.wheelPropagation;
  15. }
  16. }
  17. var scrollLeft = element.scrollLeft;
  18. if (deltaY === 0) {
  19. if (!i.scrollbarXActive) {
  20. return false;
  21. }
  22. if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
  23. return !i.settings.wheelPropagation;
  24. }
  25. }
  26. return true;
  27. }
  28. function getDeltaFromEvent(e) {
  29. var deltaX = e.deltaX;
  30. var deltaY = -1 * e.deltaY;
  31. if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
  32. // OS X Safari
  33. deltaX = -1 * e.wheelDeltaX / 6;
  34. deltaY = e.wheelDeltaY / 6;
  35. }
  36. if (e.deltaMode && e.deltaMode === 1) {
  37. // Firefox in deltaMode 1: Line scrolling
  38. deltaX *= 10;
  39. deltaY *= 10;
  40. }
  41. if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
  42. // IE in some mouse drivers
  43. deltaX = 0;
  44. deltaY = e.wheelDelta;
  45. }
  46. return [deltaX, deltaY];
  47. }
  48. function shouldBeConsumedByTextarea(deltaX, deltaY) {
  49. var hoveredTextarea = element.querySelector('textarea:hover');
  50. if (hoveredTextarea) {
  51. var maxScrollTop = hoveredTextarea.scrollHeight - hoveredTextarea.clientHeight;
  52. if (maxScrollTop > 0) {
  53. if (!(hoveredTextarea.scrollTop === 0 && deltaY > 0) &&
  54. !(hoveredTextarea.scrollTop === maxScrollTop && deltaY < 0)) {
  55. return true;
  56. }
  57. }
  58. var maxScrollLeft = hoveredTextarea.scrollLeft - hoveredTextarea.clientWidth;
  59. if (maxScrollLeft > 0) {
  60. if (!(hoveredTextarea.scrollLeft === 0 && deltaX < 0) &&
  61. !(hoveredTextarea.scrollLeft === maxScrollLeft && deltaX > 0)) {
  62. return true;
  63. }
  64. }
  65. }
  66. return false;
  67. }
  68. function mousewheelHandler(e) {
  69. var delta = getDeltaFromEvent(e);
  70. var deltaX = delta[0];
  71. var deltaY = delta[1];
  72. if (shouldBeConsumedByTextarea(deltaX, deltaY)) {
  73. return;
  74. }
  75. shouldPrevent = false;
  76. if (!i.settings.useBothWheelAxes) {
  77. // deltaX will only be used for horizontal scrolling and deltaY will
  78. // only be used for vertical scrolling - this is the default
  79. updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
  80. updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
  81. } else if (i.scrollbarYActive && !i.scrollbarXActive) {
  82. // only vertical scrollbar is active and useBothWheelAxes option is
  83. // active, so let's scroll vertical bar using both mouse wheel axes
  84. if (deltaY) {
  85. updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
  86. } else {
  87. updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
  88. }
  89. shouldPrevent = true;
  90. } else if (i.scrollbarXActive && !i.scrollbarYActive) {
  91. // useBothWheelAxes and only horizontal bar is active, so use both
  92. // wheel axes for horizontal bar
  93. if (deltaX) {
  94. updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
  95. } else {
  96. updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
  97. }
  98. shouldPrevent = true;
  99. }
  100. updateGeometry(element);
  101. shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
  102. if (shouldPrevent) {
  103. e.stopPropagation();
  104. e.preventDefault();
  105. }
  106. }
  107. if (typeof window.onwheel !== "undefined") {
  108. i.event.bind(element, 'wheel', mousewheelHandler);
  109. } else if (typeof window.onmousewheel !== "undefined") {
  110. i.event.bind(element, 'mousewheel', mousewheelHandler);
  111. }
  112. }
  113. module.exports = function (element) {
  114. var i = instances.get(element);
  115. bindMouseWheelHandler(element, i);
  116. };