PageSourceSearch

https://www.siva.edu.cn/_upload/tpl/00/03/3/template3/js/pen.js

js siva.edu.cn collected 2026-10-02 11:51:43 UTC 6,440 bytes, 191 lines download raw bytes

1(function () {
2
3  //////////////////////
4  // Utils
5  //////////////////////
6  function throttle(fn, delay, scope) {
7    // Default delay
8    delay = delay || 250;
9    var last, defer;
10    return function () {
11      var context = scope || this,
12        now = +new Date(),
13        args = arguments;
14      if (last && now < last + delay) {
15        clearTimeout(defer);
16        defer = setTimeout(function () {
17          last = now;
18          fn.apply(context, args);
19        }, delay);
20      } else {
21        last = now;
22        fn.apply(context, args);
23      }
24    };
25  }
26
27  function extend(destination, source) {
28    for (var k in source) {
29      if (source.hasOwnProperty(k)) {
30        destination[k] = source[k];
31      }
32    }
33    return destination;
34  }
35  var ScrollManager = function () {
36    var defaults = {
37      steps: null,
38      navigationContainer: null,
39      links: null,
40      scrollToTopBtn: null,
41      windowPercent: 0.7,//element出现在页面70%的地方切换
42      navigationElementClass: '.Quick-navigation',
43      currentStepClass: 'current',
44      smoothScrollEnabled: true,
45      stepsCheckEnabled: true,
46      // Callbacks
47      onScroll: null,
48      onStepChange: function (step, index) {
49        var self = this;
50        var relativeLink = [].filter.call(options.links, function (link) {
51          link.classList.remove(self.currentStepClass);
52          return link.hash === '#' + step.id;
53        });
54
55        relativeLink[0] != null && relativeLink[0].classList.add(self.currentStepClass);
56      },
57      // Provide a default scroll animation
58      smoothScrollAnimation: function (target) {
59        $('html, body').animate({
60          scrollTop: target
61        },
62          'slow');
63      }
64    },
65
66
67      options = {};
68
69    // Privates
70    var _animation = null,
71      currentStep = null,
72      throttledGetScrollPosition = null;
73
74    return {
75      scrollPosition: 0,
76      init: function (opts) {
77        options = extend(defaults, opts);
78        if (options.steps === null) {
79          console.warn('Smooth scrolling require some sections or steps to scroll to :)');
80          return false;
81        }
82        // Allow to customize the animation engine ( jQuery / GSAP / velocity / ... )
83        _animation = function (target) {
84          target = typeof target === 'number' ? target : $(target).offset().top;
85          return options.smoothScrollAnimation(target);
86        };
87
88        // Activate smooth scrolling
89        if (options.smoothScrollEnabled) this.smoothScroll();
90
91        // Scroll to top handling
92        if (options.scrollToTopBtn) {
93          options.scrollToTopBtn.addEventListener('click', function () {
94            options.smoothScrollAnimation(0);
95          });
96        }
97
98        // Throttle for performances gain
99        throttledGetScrollPosition = throttle(this.getScrollPosition).bind(this);
100        window.addEventListener('scroll', throttledGetScrollPosition);
101        window.addEventListener('resize', throttledGetScrollPosition);
102
103        this.getScrollPosition();
104      },
105
106      getScrollPosition: function () {
107        this.scrollPosition = window.pageYOffset || window.scrollY;
108        if (options.stepsCheckEnabled) this.checkActiveStep();
109        if (typeof options.onScroll === 'function') options.onScroll(this.scrollPosition);
110      },
111
112      scrollPercentage: function () {
113        var body = document.body,
114          html = document.documentElement,
115          documentHeight = Math.max(body.scrollHeight, body.offsetHeight,
116            html.clientHeight, html.scrollHeight, html.offsetHeight);
117
118        var percentage = Math.round(this.scrollPosition / (documentHeight - window.innerHeight) * 100);
119        if (percentage < 0) percentage = 0;
120        if (percentage > 100) percentage = 100;
121        return percentage;
122      },
123
124      doSmoothScroll: function (e) {
125        if (e.target.nodeName === 'A') {
126          e.preventDefault();
127          if (location.pathname.replace(/^\//, '') === e.target.pathname.replace(/^\//, '') && location.hostname === e.target.hostname) {
128            var targetStep = document.querySelector(e.target.hash);
129            targetStep ? _animation(targetStep) : console.warn('Hi! You should give an animation callback function to the Scroller module! :)');
130          }
131        }
132      },
133
134      smoothScroll: function () {
135        if (options.navigationContainer !== null) options.navigationContainer.addEventListener('click', this.doSmoothScroll);
136      },
137
138      checkActiveStep: function () {
139        var scrollPosition = this.scrollPosition;
140
141        [].forEach.call(options.steps, function (step, index) {
142          var bBox = step.getBoundingClientRect(),
143            position = step.offsetTop - $(window).height() * 0.7,
144            height = position + bBox.height;
145          if (scrollPosition >= position && scrollPosition < height && currentStep !== step) {
146            currentStep = step;
147            options.steps.forEach(function (item) {
148              item.classList.remove(defaults.currentStepClass)
149            })
150            step.classList.add(defaults.currentStepClass);
151            if (typeof options.onStepChange === 'function') options.onStepChange(step, index);
152          }
153
154          //step.classList.remove(defaults.currentStepClass);
155
156
157        });
158      },
159
160      destroy: function () {
161        window.removeEventListener('scroll', throttledGetScrollPosition);
162        window.removeEventListener('resize', throttledGetScrollPosition);
163        options.navigationContainer.removeEventListener('click', this.doSmoothScroll);
164      }
165    };
166
167  }();
168
169  function pen({ trigger = [], triggerName = [], scrollToTopBtn }) {
170    var scrollToTopBtn = document.querySelector(scrollToTopBtn),
171      steps = [],
172      navigationContainer = document.querySelector('.Quick-navigation'),
173      links = []
174    trigger.forEach(function (item, index) {
175      steps.push(document.querySelector(item))
176      const newsEle = document.createElement("a")
177      newsEle.innerText = triggerName[index]
178      newsEle.classList.add("Quick-navigation-item")
179      newsEle.setAttribute("href", "#" + document.querySelector(item).getAttribute("id"))
180      navigationContainer.appendChild(newsEle)
181      links.push(newsEle)
182    })
183    ScrollManager.init({
184      steps: steps,
185      scrollToTopBtn: scrollToTopBtn,
186      navigationContainer: navigationContainer,
187      links: links,
188    });
189  }
190  window.pen = pen
191})(jQuery, window, document);

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.