Blame view

天文台pc/tianwentai-ui/node_modules/react-remove-scroll/dist/es2019/handleScroll.js 4.05 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  const alwaysContainsScroll = (node) => 
  // textarea will always _contain_ scroll inside self. It only can be hidden
  node.tagName === 'TEXTAREA';
  const elementCanBeScrolled = (node, overflow) => {
      if (!(node instanceof Element)) {
          return false;
      }
      const styles = window.getComputedStyle(node);
      return (
      // not-not-scrollable
      styles[overflow] !== 'hidden' &&
          // contains scroll inside self
          !(styles.overflowY === styles.overflowX && !alwaysContainsScroll(node) && styles[overflow] === 'visible'));
  };
  const elementCouldBeVScrolled = (node) => elementCanBeScrolled(node, 'overflowY');
  const elementCouldBeHScrolled = (node) => elementCanBeScrolled(node, 'overflowX');
  export const locationCouldBeScrolled = (axis, node) => {
      const ownerDocument = node.ownerDocument;
      let current = node;
      do {
          // Skip over shadow root
          if (typeof ShadowRoot !== 'undefined' && current instanceof ShadowRoot) {
              current = current.host;
          }
          const isScrollable = elementCouldBeScrolled(axis, current);
          if (isScrollable) {
              const [, scrollHeight, clientHeight] = getScrollVariables(axis, current);
              if (scrollHeight > clientHeight) {
                  return true;
              }
          }
          current = current.parentNode;
      } while (current && current !== ownerDocument.body);
      return false;
  };
  const getVScrollVariables = ({ scrollTop, scrollHeight, clientHeight }) => [
      scrollTop,
      scrollHeight,
      clientHeight,
  ];
  const getHScrollVariables = ({ scrollLeft, scrollWidth, clientWidth }) => [
      scrollLeft,
      scrollWidth,
      clientWidth,
  ];
  const elementCouldBeScrolled = (axis, node) => axis === 'v' ? elementCouldBeVScrolled(node) : elementCouldBeHScrolled(node);
  const getScrollVariables = (axis, node) => axis === 'v' ? getVScrollVariables(node) : getHScrollVariables(node);
  const getDirectionFactor = (axis, direction) => 
  /**
   * If the element's direction is rtl (right-to-left), then scrollLeft is 0 when the scrollbar is at its rightmost position,
   * and then increasingly negative as you scroll towards the end of the content.
   * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
   */
  axis === 'h' && direction === 'rtl' ? -1 : 1;
  export const handleScroll = (axis, endTarget, event, sourceDelta, noOverscroll) => {
      const directionFactor = getDirectionFactor(axis, window.getComputedStyle(endTarget).direction);
      const delta = directionFactor * sourceDelta;
      // find scrollable target
      let target = event.target;
      const targetInLock = endTarget.contains(target);
      let shouldCancelScroll = false;
      const isDeltaPositive = delta > 0;
      let availableScroll = 0;
      let availableScrollTop = 0;
      do {
          if (!target) {
              break;
          }
          const [position, scroll, capacity] = getScrollVariables(axis, target);
          const elementScroll = scroll - capacity - directionFactor * position;
          if (position || elementScroll) {
              if (elementCouldBeScrolled(axis, target)) {
                  availableScroll += elementScroll;
                  availableScrollTop += position;
              }
          }
          const parent = target.parentNode;
          // we will "bubble" from ShadowDom in case we are, or just to the parent in normal case
          // this is the same logic used in focus-lock
          target = (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? parent.host : parent);
      } while (
      // portaled content
      (!targetInLock && target !== document.body) ||
          // self content
          (targetInLock && (endTarget.contains(target) || endTarget === target)));
      // handle epsilon around 0 (non standard zoom levels)
      if (isDeltaPositive &&
          ((noOverscroll && Math.abs(availableScroll) < 1) || (!noOverscroll && delta > availableScroll))) {
          shouldCancelScroll = true;
      }
      else if (!isDeltaPositive &&
          ((noOverscroll && Math.abs(availableScrollTop) < 1) || (!noOverscroll && -delta > availableScrollTop))) {
          shouldCancelScroll = true;
      }
      return shouldCancelScroll;
  };