PageSourceSearch

https://concerts.zapomni.ru/assets/lib/bodyScrollLock.js

js zapomni.ru collected 2026-10-02 06:51:35 UTC 10,686 bytes, 347 lines download raw bytes

1(function (global, factory) {
2  if (typeof define === 'function' && define.amd) {
3    define(['exports'], factory);
4  } else if (typeof exports !== 'undefined') {
5    factory(exports);
6  } else {
7    var mod = {
8      exports: {},
9    };
10    factory(mod.exports);
11    global.bodyScrollLock = mod.exports;
12  }
13})(this, function (exports) {
14  'use strict';
15
16  Object.defineProperty(exports, '__esModule', {
17    value: true,
18  });
19
20  function _toConsumableArray(arr) {
21    if (Array.isArray(arr)) {
22      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
23        arr2[i] = arr[i];
24      }
25
26      return arr2;
27    } else {
28      return Array.from(arr);
29    }
30  }
31
32  // Older browsers don't support event options, feature detect it.
33
34  // Adopted and modified solution from Bohdan Didukh (2017)
35  // https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
36
37  var hasPassiveEvents = false;
38  if (typeof window !== 'undefined') {
39    var passiveTestOptions = {
40      get passive() {
41        hasPassiveEvents = true;
42        return undefined;
43      },
44    };
45    window.addEventListener('testPassive', null, passiveTestOptions);
46    window.removeEventListener('testPassive', null, passiveTestOptions);
47  }
48
49  var isIosDevice =
50    typeof window !== 'undefined' &&
51    window.navigator &&
52    window.navigator.platform &&
53    (/iP(ad|hone|od)/.test(window.navigator.platform) ||
54      (window.navigator.platform === 'MacIntel' &&
55        window.navigator.maxTouchPoints > 1));
56
57  var locks = [];
58  var documentListenerAdded = false;
59  var initialClientY = -1;
60  var previousBodyOverflowSetting = void 0;
61  var previousBodyPosition = void 0;
62  var previousBodyPaddingRight = void 0;
63
64  // returns true if `el` should be allowed to receive touchmove events.
65  var allowTouchMove = function allowTouchMove(el) {
66    return locks.some(function (lock) {
67      if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {
68        return true;
69      }
70
71      return false;
72    });
73  };
74
75  var preventDefault = function preventDefault(rawEvent) {
76    var e = rawEvent || window.event;
77
78    // For the case whereby consumers adds a touchmove event listener to document.
79    // Recall that we do document.addEventListener('touchmove', preventDefault, { passive: false })
80    // in disableBodyScroll - so if we provide this opportunity to allowTouchMove, then
81    // the touchmove event on document will break.
82    if (allowTouchMove(e.target)) {
83      return true;
84    }
85
86    // Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
87    if (e.touches.length > 1) return true;
88
89    if (e.preventDefault) e.preventDefault();
90
91    return false;
92  };
93
94  var setOverflowHidden = function setOverflowHidden(options) {
95    // If previousBodyPaddingRight is already set, don't set it again.
96    if (previousBodyPaddingRight === undefined) {
97      var _reserveScrollBarGap =
98        !!options && options.reserveScrollBarGap === true;
99      var scrollBarGap =
100        window.innerWidth - document.documentElement.clientWidth;
101
102      if (_reserveScrollBarGap && scrollBarGap > 0) {
103        var computedBodyPaddingRight = parseInt(
104          window
105            .getComputedStyle(document.body)
106            .getPropertyValue('padding-right'),
107          10
108        );
109        previousBodyPaddingRight = document.body.style.paddingRight;
110        document.body.style.paddingRight =
111          computedBodyPaddingRight + scrollBarGap + 'px';
112      }
113    }
114
115    // If previousBodyOverflowSetting is already set, don't set it again.
116    if (previousBodyOverflowSetting === undefined) {
117      previousBodyOverflowSetting = document.body.style.overflow;
118      document.body.style.overflow = 'hidden';
119    }
120  };
121
122  var restoreOverflowSetting = function restoreOverflowSetting() {
123    if (previousBodyPaddingRight !== undefined) {
124      document.body.style.paddingRight = previousBodyPaddingRight;
125
126      // Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it
127      // can be set again.
128      previousBodyPaddingRight = undefined;
129    }
130
131    if (previousBodyOverflowSetting !== undefined) {
132      document.body.style.overflow = previousBodyOverflowSetting;
133
134      // Restore previousBodyOverflowSetting to undefined
135      // so setOverflowHidden knows it can be set again.
136      previousBodyOverflowSetting = undefined;
137    }
138  };
139
140  var setPositionFixed = function setPositionFixed() {
141    return window.requestAnimationFrame(function () {
142      // If previousBodyPosition is already set, don't set it again.
143      if (previousBodyPosition === undefined) {
144        previousBodyPosition = {
145          position: document.body.style.position,
146          top: document.body.style.top,
147          left: document.body.style.left,
148        };
149
150        // Update the dom inside an animation frame
151        var _window = window,
152          scrollY = _window.scrollY,
153          scrollX = _window.scrollX,
154          innerHeight = _window.innerHeight;
155
156        document.body.style.position = 'fixed';
157        document.body.style.top = -scrollY;
158        document.body.style.left = -scrollX;
159
160        setTimeout(function () {
161          return window.requestAnimationFrame(function () {
162            // Attempt to check if the bottom bar appeared due to the position change
163            var bottomBarHeight = innerHeight - window.innerHeight;
164            if (bottomBarHeight && scrollY >= innerHeight) {
165              // Move the content further up so that the bottom bar doesn't hide it
166              document.body.style.top = -(scrollY + bottomBarHeight);
167            }
168          });
169        }, 300);
170      }
171    });
172  };
173
174  var restorePositionSetting = function restorePositionSetting() {
175    if (previousBodyPosition !== undefined) {
176      // Convert the position from "px" to Int
177      var y = -parseInt(document.body.style.top, 10);
178      var x = -parseInt(document.body.style.left, 10);
179
180      // Restore styles
181      document.body.style.position = previousBodyPosition.position;
182      document.body.style.top = previousBodyPosition.top;
183      document.body.style.left = previousBodyPosition.left;
184
185      // Restore scroll
186      window.scrollTo(x, y);
187
188      previousBodyPosition = undefined;
189    }
190  };
191
192  // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
193  var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled(
194    targetElement
195  ) {
196    return targetElement
197      ? targetElement.scrollHeight - targetElement.scrollTop <=
198          targetElement.clientHeight
199      : false;
200  };
201
202  var handleScroll = function handleScroll(event, targetElement) {
203    var clientY = event.targetTouches[0].clientY - initialClientY;
204
205    if (allowTouchMove(event.target)) {
206      return false;
207    }
208
209    if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
210      // element is at the top of its scroll.
211      return preventDefault(event);
212    }
213
214    if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
215      // element is at the bottom of its scroll.
216      return preventDefault(event);
217    }
218
219    event.stopPropagation();
220    return true;
221  };
222
223  var disableBodyScroll = (exports.disableBodyScroll =
224    function disableBodyScroll(targetElement, options) {
225      // targetElement must be provided
226      if (!targetElement) {
227        // eslint-disable-next-line no-console
228        console.error(
229          'disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.'
230        );
231        return;
232      }
233
234      // disableBodyScroll must not have been called on this targetElement before
235      if (
236        locks.some(function (lock) {
237          return lock.targetElement === targetElement;
238        })
239      ) {
240        return;
241      }
242
243      var lock = {
244        targetElement: targetElement,
245        options: options || {},
246      };
247
248      locks = [].concat(_toConsumableArray(locks), [lock]);
249
250      if (isIosDevice) {
251        setPositionFixed();
252      } else {
253        setOverflowHidden(options);
254      }
255
256      if (isIosDevice) {
257        targetElement.ontouchstart = function (event) {
258          if (event.targetTouches.length === 1) {
259            // detect single touch.
260            initialClientY = event.targetTouches[0].clientY;
261          }
262        };
263        targetElement.ontouchmove = function (event) {
264          if (event.targetTouches.length === 1) {
265            // detect single touch.
266            handleScroll(event, targetElement);
267          }
268        };
269
270        if (!documentListenerAdded) {
271          document.addEventListener(
272            'touchmove',
273            preventDefault,
274            hasPassiveEvents ? { passive: false } : undefined
275          );
276          documentListenerAdded = true;
277        }
278      }
279    });
280
281  var clearAllBodyScrollLocks = (exports.clearAllBodyScrollLocks =
282    function clearAllBodyScrollLocks() {
283      if (isIosDevice) {
284        // Clear all locks ontouchstart/ontouchmove handlers, and the references.
285        locks.forEach(function (lock) {
286          lock.targetElement.ontouchstart = null;
287          lock.targetElement.ontouchmove = null;
288        });
289
290        if (documentListenerAdded) {
291          document.removeEventListener(
292            'touchmove',
293            preventDefault,
294            hasPassiveEvents ? { passive: false } : undefined
295          );
296          documentListenerAdded = false;
297        }
298
299        // Reset initial clientY.
300        initialClientY = -1;
301      }
302
303      if (isIosDevice) {
304        restorePositionSetting();
305      } else {
306        restoreOverflowSetting();
307      }
308
309      locks = [];
310    });
311
312  var enableBodyScroll = (exports.enableBodyScroll = function enableBodyScroll(
313    targetElement
314  ) {
315    if (!targetElement) {
316      // eslint-disable-next-line no-console
317      console.error(
318        'enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.'
319      );
320      return;
321    }
322
323    locks = locks.filter(function (lock) {
324      return lock.targetElement !== targetElement;
325    });
326
327    if (isIosDevice) {
328      targetElement.ontouchstart = null;
329      targetElement.ontouchmove = null;
330
331      if (documentListenerAdded && locks.length === 0) {
332        document.removeEventListener(
333          'touchmove',
334          preventDefault,
335          hasPassiveEvents ? { passive: false } : undefined
336        );
337        documentListenerAdded = false;
338      }
339    }
340
341    if (isIosDevice) {
342      restorePositionSetting();
343    } else {
344      restoreOverflowSetting();
345    }
346  });
347});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.