PageSourceSearch

https://www.xjtlu.edu.cn/wp-content/themes/xjtlu/assets/js/util.js?ver=1.7

js xjtlu.edu.cn collected 2026-09-24 08:46:40 UTC 10,670 bytes, 277 lines download raw bytes

1// SpyScroll JS
2!function(t,e,a,n){t.fn.extend({scrollspy:function(n){n=t.extend({},{namespace:"scrollspy",activeClass:"active",animate:!1,duration:1e3,offset:0,container:e,replaceState:!1},n);var o=function(t,e){return parseInt(t,10)+parseInt(e,10)},r=function(e){for(var a=[],n=0;n<e.length;n++){var o=t(e[n]).attr("href"),r=t(o);if(r.length>0){var f=Math.floor(r.offset().top),i=f+Math.floor(r.outerHeight());a.push({element:r,hash:o,top:f,bottom:i})}}return a},f=function(e,a){for(var n=0;n<e.length;n++){var o=t(e[n]);if(o.attr("href")===a)return o}},i=function(e){for(var a=0;a<e.length;a++)t(e[a]).parent().removeClass(n.activeClass)},l="";return this.each(function(){for(var s=this,c=t(n.container),h=t(s).find("a"),p=0;p<h.length;p++)t(h[p]).on("click",function(a){var r=t(this).attr("href"),f=t(r);if(f.length>0){var i=o(f.offset().top,n.offset);n.animate?t("html, body").animate({scrollTop:i},n.duration):e.scrollTo(0,i),a.preventDefault()}});i(h);var v=r(h),u=function(){for(var e,a={top:o(t(this).scrollTop(),Math.abs(n.offset)),left:t(this).scrollLeft()},r=0;r<v.length;r++){var c=v[r];if(a.top>=c.top&&a.top<c.bottom){var p=c.hash;if(e=f(h,p)){n.onChange&&l!==p&&(n.onChange(c.element,t(s),a),l=p),n.replaceState&&history.replaceState({},"","/"+p),i(h),e.parent().addClass(n.activeClass);break}}}!e&&"exit"!==l&&n.onExit&&(n.onExit(t(s),a),i(h),l="exit",n.replaceState&&history.replaceState({},"","/"))};c.bind("scroll."+n.namespace,function(t,e){e&&(n.offset=e),u()}),t(a).ready(function(t){u()})})}})}(jQuery,window,document,void 0);
3
4var hasInitDarkHeader = $('#top-header').hasClass('dark')
5
6// 停止所有在播放的视频
7function stopAllVideos() {
8    let videos = document.getElementsByTagName('video');
9    $.each(videos, function (index, value) {
10        if (value) {
11            value.pause()
12        }
13    })
14}
15
16/**
17 * 检测页面元素是否在可视范围
18 */
19function isElementInViewport(el) {
20    if (typeof jQuery === "function" && el instanceof jQuery) {
21        el = el[0];
22    }
23
24    var rect = el.getBoundingClientRect();
25
26    return (
27        rect.top >= 0 &&
28        rect.left >= 0 &&
29        rect.top <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
30        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
31    );
32}
33
34/**
35 * 配合 isElementInViewport 函数实现页面滚动时触发页面元素出现在可视范围内时的回调
36 * 
37 * 使用示例
38 * 
39 * $(window).on('DOMContentLoaded load resize scroll', onVisibilityChange($('.myelm'), function() {
40 *      console.log('shown...');
41 * }));
42 */
43function onVisibilityChange(el, callback) {
44    var old_visible = false;
45    return function () {
46        var visible = isElementInViewport(el);
47        if (visible != old_visible) {
48            old_visible = visible;
49            if (typeof callback == 'function') {
50                callback();
51            }
52        }
53    }
54}
55
56var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame;
57
58// 背景图片跟随屏幕滚动移动方法
59function parallaxScroll() {
60
61    var windowOffset = document.body.scrollTop;
62
63    var lastPosition = -1;
64    if (lastPosition == windowOffset) {
65
66        requestAnimationFrame(parallaxScroll);
67        return false;
68    } else lastPosition = windowOffset;
69
70    var parallaxElements = document.querySelectorAll('[data-parallax]');
71    var i;
72    for (i = 0; i < parallaxElements.length; i++) {
73
74        var el = parallaxElements[i];
75        var parent = el.parentNode;
76
77        var parentHeight = parent.getBoundingClientRect().height;
78        var parentOffset = parent.getBoundingClientRect().top + parentHeight / 2;
79        var finalOffset = window.innerHeight / 2 - parentOffset;
80        var translate = finalOffset * el.getAttribute('data-parallax');
81
82        if (el.getAttribute('data-no-mobile') && window.innerWidth < 768) {
83            el.style.transform = 'translate3d(0,0,0)';
84        } else {
85            el.style.transform = 'translate3d(0,' + translate.toFixed(1) + 'px, 0)';
86        }
87    }
88
89    requestAnimationFrame(parallaxScroll);
90}
91
92/**
93 * 页面滚动到指定位置时给指定元素添加class
94 */
95function scrollInEffect() {
96    // data-scrollin属性数据是一个数组,如:[-900, -600, -550],数组中第一个是桌面版触发的距离的offset,第二个是平板版,第三个是手机版
97    var scrollInElements = document.querySelectorAll('[data-scrollin]');
98    var elements = [];
99    for (var i = 0; i < scrollInElements.length; i++) {
100        var el = scrollInElements[i];
101        var offset = el.getAttribute('data-scrollin');
102        offset = JSON.parse(offset);
103        var effectClass = el.getAttribute('data-scrollin-class');
104        var elementPositionY = el.getBoundingClientRect().top;
105        elements.push({
106            class: effectClass,
107            offsets: offset,
108            top: elementPositionY,
109            dom: el,
110            hasReached: false
111        });
112    }
113    function onScrolling() {
114        var windowTop = $(window).scrollTop();
115        var screenWidth = $(window).width();
116        var offsetIdx;
117        if (screenWidth > 1400) {
118            offsetIdx = 0;
119        } else if (screenWidth > 560 && screenWidth <= 1400) {
120            offsetIdx = 1;
121        } else {
122            offsetIdx = 2;
123        }
124
125        var numReached = 0;
126        for (var i = 0; i < elements.length; i++) {
127            var el = elements[i];
128            if (!el.hasReached && windowTop >= el.top + el.offsets[offsetIdx]) {
129                $(el.dom).addClass(el.class);
130                el.hasReached = true;
131                numReached++;
132            }
133            else if (el.hasReached) {
134                numReached++;
135            }
136        }
137        if (numReached < elements.length) {
138            requestAnimationFrame(onScrolling);
139        }
140    }
141
142    if (elements.length > 0) {
143        requestAnimationFrame(onScrolling);
144    }
145}
146
147
148/**
149 * 用来控制页面滚动一定距离后,页面顶部添加相应的class
150 */
151function pageScrollHeaderChange() {
152    $(window).scroll(function () {
153
154        if (hasInitDarkHeader) {
155            if ($(window).scrollTop() > 36) {
156                $('#top-header').removeClass('dark')
157                $('#top-header').addClass('stick')
158            } else {
159                if ($('#top-header').hasClass('xjtlu-light-white')) {
160                    $('#top-header').addClass('stick')
161
162                } else {
163                    $('#top-header').addClass('dark')
164                    $('#top-header').removeClass('stick')
165                }
166            }
167
168        } else {
169            if ($(window).scrollTop() > 36) {
170                $('#top-header').addClass('stick')
171
172            } else {
173                if ($('#top-header').hasClass('xjtlu-light-white')) {
174                    $('#top-header').addClass('stick')
175
176                } else {
177                    if ($('#top-header').hasClass('xjtlu-light-white')) {
178                        $('#top-header').addClass('stick')
179
180                    } else {
181                        $('#top-header').removeClass('stick')
182                    }
183                }
184            }
185        }
186    })
187
188}
189
190function initScrollSpy(selector) {
191    if($(selector).length > 0) {
192        var topV = '85px'
193        let winWide = $(window).width();
194        if(winWide > 1400) {
195            $('.anchor-bar-box').css('top','85px')
196            // 监听anchor-bar-box是否固定
197            const sticky = document.querySelector('.anchor-bar-box')
198            const observer = new IntersectionObserver((entries) => {
199            entries.forEach(entry => {
200                entry.target.classList.toggle('anchor-is-fixed', entry.intersectionRatio === 0)
201            })
202            }, { threshold: [0, 1], rootMargin: '-163px 0px 0px 0px' }) // 163为元素高度加上头部距离
203            observer.observe(sticky)
204        }
205        if(winWide > 560 && winWide <= 960) {
206            if($('.sidebar').length > 0) {
207                topV  = $('.sidebar').outerHeight() + 60 + 'px'
208            }
209            $('.anchor-bar-box').css('top',topV)
210        }
211        if(winWide <= 560) {
212            if($('.sidebar').length > 0) {
213                topV  = $('.sidebar').outerHeight() + 60 + 'px'
214            }
215            $('.anchor-bar-box').css('top',topV)
216        }
217
218        var offset;
219        if (winWide > 1400) {
220            offset = -180
221        } else if (winWide > 560 && winWide <= 960) {
222            offset = -($('.anchor-bar').height() + 175);
223        } else {
224            offset = -($('.anchor-bar').height() + 310);
225        }
226        $(selector).scrollspy({ offset: offset });
227    }
228}
229
230
231function onResizeScrollSpy()
232{
233    var offset;
234    let winWide = $(window).width();
235    if (winWide > 1400) {
236        offset = -173
237    } else if (winWide > 560 && winWide <= 960) {
238        offset = -($('.anchor-bar').height() + 175);
239    } else {
240        offset = -($('.anchor-bar').height() + 310);
241    }
242    $(window).trigger('scroll.scrollspy', offset);
243}
244
245// 导航栏菜单内容超出屏幕
246function headerNav() {
247    if (window.innerWidth > 960) {
248        $('.menu-item').hover(function() {
249            var $element = $(this).find('.down-box');
250            var originalWidth = $element.data('originalWidth') || $element.width();
251            $element.data('originalWidth', originalWidth);
252            if ($(document.documentElement).width() < originalWidth || isOutOfScreen($element)) {
253                $element.addClass('fixedCenter');
254                if (originalWidth > window.innerWidth) {
255                    $element.addClass('widthAuto');
256                }
257                var elementRect = $element[0].getBoundingClientRect();
258                if (elementRect.bottom > window.innerHeight) {
259                    $element.addClass('scroll-style');
260
261                }
262            }
263        }, function() {
264            $(this).find('.down-box').removeClass('fixedCenter widthAuto scroll-style');
265        });
266    }
267}
268
269function isOutOfScreen($element) {
270    var elementRect = $element[0].getBoundingClientRect();
271    return (
272        elementRect.left < 0 ||
273        elementRect.right > window.innerWidth ||
274        elementRect.top < 0 ||
275        elementRect.bottom > window.innerHeight
276    );
277}

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.