Source: customEvent/scrollEnd.js

  1. /**
  2. * Copyright (c) 2015 NAVER Corp.
  3. * egjs projects are licensed under the MIT license
  4. */
  5. // jscs:disable maximumLineLength
  6. eg.module("scrollEnd", ["jQuery", eg, window], function($, ns, global) {
  7. "use strict";
  8. // jscs:eable maximumLineLength
  9. /**
  10. * A custom event in jQuery occurs when scroll ends.
  11. * @ko 스크롤이 끝날 때 발생하는 jQuery 커스텀 이벤트
  12. * @name jQuery#scrollEnd
  13. * @event
  14. * @param {Event} e The Event object in jQuery <ko>jQuery의 Event 객체</ko>
  15. * @param {Object} info The object of data to be sent when the event is fired<ko>이벤트가 발생할 때 전달되는 데이터 객체</ko>
  16. * @param {Number} info.top The size of the vertical scroll pane (unit: px)<ko>세로 스크롤 영역의 크기(단위: px)</ko>
  17. * @param {Number} info.left The size of horizontal scroll pane (unit: px)<ko>가로 스크롤 영역의 크기(단위: px)</ko>
  18. * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
  19. * @example
  20. * $(window).on("scrollend",function(e, info){
  21. * info.top;
  22. * info.left;
  23. * });
  24. *
  25. */
  26. var scrollEndTimer;
  27. var userAgent = global.navigator.userAgent;
  28. var rotateFlag = false;
  29. var CHROME = 3;
  30. var TIMERBASE = 2;
  31. var TOUCHBASE = 1;
  32. var SCROLLBASE = 0;
  33. var latency = 250;
  34. var detectType = getDetectType(userAgent);
  35. $.event.special.scrollend = {
  36. setup: function() {
  37. attachEvent();
  38. },
  39. teardown: function() {
  40. removeEvent();
  41. }
  42. };
  43. /**
  44. * iOS & Safari:
  45. * iOS7 and lower, scroll event occurs once when the scroll is stopped
  46. * iOS8 and upper, scroll event occurs on every scroll
  47. * Scroll event occurs when the rotation
  48. * Android:
  49. * Scroll event occurs on every scroll
  50. * Scroll event occurs on rotation and should be ignored to handle
  51. * @ko
  52. * iOS & Safari :
  53. * iOS 7.x 이하에서는 스크롤이 멈췄을때 scroll 이벤트 한번 발생
  54. * iOS 8.x 이상에서는 scroll 이벤트가 android 와 동일하게 스크롤시 매번 발생
  55. * 회전시 scroll 이벤트가 발생되어 이를 무시처리해야함
  56. * (orientationchange 에 의해 발생하는 scroll 이벤트 1회만 무시)
  57. * Android :
  58. * 스크롤시 scroll 이벤트 매번 발생
  59. * 회전시 scroll 이벤트가 발생되어 이를 무시 처리해야 함
  60. */
  61. function getDetectType(userAgent) {
  62. var deviceName;
  63. var osVersion;
  64. var retValue = TIMERBASE;
  65. var matchedDevice = userAgent.match(/iPhone|iPad|Android/);
  66. var webviewToken = /NAVER|DAUM|; wv/;
  67. var webviewToken2 = /Version/;
  68. // webview : TIMERBASE
  69. if (matchedDevice !== null && !webviewToken.test(userAgent)) {
  70. deviceName = matchedDevice[0];
  71. // Browsers that trigger scroll event like scrollstop : SCROLLBASE
  72. osVersion = userAgent.match(/\s(\d{1,2})_\d/);
  73. if (deviceName !== "Android" && webviewToken2.test(userAgent) && osVersion && parseInt(osVersion[1], 10) <= 7) {
  74. retValue = SCROLLBASE;
  75. } else if (deviceName === "Android") {
  76. osVersion = userAgent.match(/Android\b(.*?);/);
  77. if (!/Chrome/.test(userAgent) && osVersion && parseFloat(osVersion) <= 2.3) {
  78. retValue = SCROLLBASE;
  79. }
  80. }
  81. }
  82. return retValue;
  83. }
  84. function attachEvent() {
  85. $(global).on("scroll", scroll);
  86. $(global).on("orientationchange", onOrientationchange);
  87. }
  88. function onOrientationchange() {
  89. rotateFlag = true;
  90. }
  91. function scroll() {
  92. if (rotateFlag) {
  93. rotateFlag = false;
  94. return;
  95. }
  96. switch (detectType) {
  97. case SCROLLBASE :
  98. triggerScrollEnd();
  99. break;
  100. case TIMERBASE :
  101. triggerScrollEndAlways();
  102. break;
  103. }
  104. }
  105. function triggerScrollEnd() {
  106. $(global).trigger("scrollend", {
  107. top: global.pageYOffset,
  108. left: global.pageXOffset
  109. });
  110. }
  111. function triggerScrollEndAlways() {
  112. clearTimeout(scrollEndTimer);
  113. scrollEndTimer = setTimeout(function() {
  114. if (rotateFlag) {
  115. rotateFlag = false;
  116. return;
  117. }
  118. triggerScrollEnd();
  119. }, latency);
  120. }
  121. function removeEvent() {
  122. $(global).off("scroll", scroll);
  123. $(global).off("orientationchange", onOrientationchange);
  124. }
  125. return {
  126. detectType: detectType,
  127. getDetectType: getDetectType,
  128. CHROME: CHROME,
  129. TIMERBASE: TIMERBASE,
  130. TOUCHBASE: TOUCHBASE,
  131. SCROLLBASE: SCROLLBASE
  132. };
  133. });
comments powered by Disqus