scrollLocker.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = void 0;
  7. var _getScrollBarSize = _interopRequireDefault(require("../../_util/getScrollBarSize"));
  8. var _setStyle = _interopRequireDefault(require("../../_util/setStyle"));
  9. let locks = [];
  10. const scrollingEffectClassName = 'ant-scrolling-effect';
  11. const scrollingEffectClassNameReg = new RegExp(`${scrollingEffectClassName}`, 'g');
  12. let uuid = 0;
  13. // https://github.com/ant-design/ant-design/issues/19340
  14. // https://github.com/ant-design/ant-design/issues/19332
  15. const cacheStyle = new Map();
  16. class ScrollLocker {
  17. constructor(options) {
  18. this.getContainer = () => {
  19. var _a;
  20. return (_a = this.options) === null || _a === void 0 ? void 0 : _a.container;
  21. };
  22. // if options change...
  23. this.reLock = options => {
  24. const findLock = locks.find(_ref => {
  25. let {
  26. target
  27. } = _ref;
  28. return target === this.lockTarget;
  29. });
  30. if (findLock) {
  31. this.unLock();
  32. }
  33. this.options = options;
  34. if (findLock) {
  35. findLock.options = options;
  36. this.lock();
  37. }
  38. };
  39. this.lock = () => {
  40. var _a;
  41. // If lockTarget exist return
  42. if (locks.some(_ref2 => {
  43. let {
  44. target
  45. } = _ref2;
  46. return target === this.lockTarget;
  47. })) {
  48. return;
  49. }
  50. // If same container effect, return
  51. if (locks.some(_ref3 => {
  52. let {
  53. options
  54. } = _ref3;
  55. var _a;
  56. return (options === null || options === void 0 ? void 0 : options.container) === ((_a = this.options) === null || _a === void 0 ? void 0 : _a.container);
  57. })) {
  58. locks = [...locks, {
  59. target: this.lockTarget,
  60. options: this.options
  61. }];
  62. return;
  63. }
  64. let scrollBarSize = 0;
  65. const container = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.container) || document.body;
  66. if (container === document.body && window.innerWidth - document.documentElement.clientWidth > 0 || container.scrollHeight > container.clientHeight) {
  67. scrollBarSize = (0, _getScrollBarSize.default)();
  68. }
  69. const containerClassName = container.className;
  70. if (locks.filter(_ref4 => {
  71. let {
  72. options
  73. } = _ref4;
  74. var _a;
  75. return (options === null || options === void 0 ? void 0 : options.container) === ((_a = this.options) === null || _a === void 0 ? void 0 : _a.container);
  76. }).length === 0) {
  77. cacheStyle.set(container, (0, _setStyle.default)({
  78. width: scrollBarSize !== 0 ? `calc(100% - ${scrollBarSize}px)` : undefined,
  79. overflow: 'hidden',
  80. overflowX: 'hidden',
  81. overflowY: 'hidden'
  82. }, {
  83. element: container
  84. }));
  85. }
  86. // https://github.com/ant-design/ant-design/issues/19729
  87. if (!scrollingEffectClassNameReg.test(containerClassName)) {
  88. const addClassName = `${containerClassName} ${scrollingEffectClassName}`;
  89. container.className = addClassName.trim();
  90. }
  91. locks = [...locks, {
  92. target: this.lockTarget,
  93. options: this.options
  94. }];
  95. };
  96. this.unLock = () => {
  97. var _a;
  98. const findLock = locks.find(_ref5 => {
  99. let {
  100. target
  101. } = _ref5;
  102. return target === this.lockTarget;
  103. });
  104. locks = locks.filter(_ref6 => {
  105. let {
  106. target
  107. } = _ref6;
  108. return target !== this.lockTarget;
  109. });
  110. if (!findLock || locks.some(_ref7 => {
  111. let {
  112. options
  113. } = _ref7;
  114. var _a;
  115. return (options === null || options === void 0 ? void 0 : options.container) === ((_a = findLock.options) === null || _a === void 0 ? void 0 : _a.container);
  116. })) {
  117. return;
  118. }
  119. // Remove Effect
  120. const container = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.container) || document.body;
  121. const containerClassName = container.className;
  122. if (!scrollingEffectClassNameReg.test(containerClassName)) return;
  123. (0, _setStyle.default)(cacheStyle.get(container), {
  124. element: container
  125. });
  126. cacheStyle.delete(container);
  127. container.className = container.className.replace(scrollingEffectClassNameReg, '').trim();
  128. };
  129. // eslint-disable-next-line no-plusplus
  130. this.lockTarget = uuid++;
  131. this.options = options;
  132. }
  133. }
  134. exports.default = ScrollLocker;