PageSourceSearch

https://0hm.cn/resource/js/custom.js

js 0hm.cn collected 2026-10-09 04:34:27 UTC 15,939 bytes, 448 lines download raw bytes

1(function($) {
2
3    "use strict";
4    $.fn.travelGemPortfolio = function() {
5        return this.each(function(i, elem) {
6            var portfolioContainer = jQuery('.portfolio-container', elem);
7            portfolioContainer.imagesLoaded(function() {
8                portfolioContainer.isotope({
9                    filter: '*',
10                    animationOptions: {
11                        duration: 750,
12                        easing: 'linear',
13                        queue: false
14                    }
15                });
16            });
17            jQuery('.portfolio-filter a', elem).on('click', function(e) {
18                e.preventDefault();
19                jQuery('.portfolio-filter .current', elem).removeClass('current');
20                jQuery(this).addClass('current');
21
22                var selector = jQuery(this).attr('data-filter');
23                portfolioContainer.isotope({
24                    filter: selector,
25                    animationOptions: {
26                        duration: 750,
27                        easing: 'linear',
28                        queue: false
29                    }
30                });
31                return false;
32            });
33        });
34    };
35
36    $(document).ready(function($) {
37        $('.portfolio-main-wrapper').travelGemPortfolio();
38
39        $.fn.viewportChecker = function(useroptions) {
40            // Define options and extend with user.
41            var options = {
42                classToAdd: 'visible',
43                offset: 100,
44                callbackFunction: function(elem) {}
45            };
46            $.extend(options, useroptions);
47
48            // Cache the given element and height of the browser
49            var $elem = this,
50                windowHeight = $(window).height();
51
52            this.checkElements = function() {
53                // Set some vars to check with
54                var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html'),
55                    viewportTop = $(scrollElem).scrollTop(),
56                    viewportBottom = (viewportTop + windowHeight);
57
58                $elem.each(function() {
59                    var $obj = $(this);
60                    // If class already exists; quit
61                    if ($obj.hasClass(options.classToAdd)) {
62                        return;
63                    }
64
65                    // define the top position of the element and include the offset which makes is appear earlier or later
66                    var elemTop = Math.round($obj.offset().top) + options.offset,
67                        elemBottom = elemTop + ($obj.height());
68
69                    // Add class if in viewport
70                    if ((elemTop < viewportBottom) && (elemBottom > viewportTop)) {
71                        $obj.addClass(options.classToAdd);
72
73                        // Do the callback function. Callback will send the jQuery object as parameter
74                        options.callbackFunction($obj);
75                    }
76                });
77            };
78
79            // Run checkelements on load and scroll.
80            $(window).on('scroll', this.checkElements);
81            this.checkElements();
82
83            // On resize change the height var.
84            $(window).on('resize', function(e) {
85                windowHeight = e.currentTarget.innerHeight;
86            });
87
88        };
89
90        // Search in header.
91        if ($('.search-icon').length > 0) {
92            $('.search-icon').on('click', function(e) {
93                e.preventDefault();
94                $('.search-box-wrap').slideToggle();
95            });
96        }
97
98        // 页面滚动加载
99        $(window).scroll(function () {
100            var st = $(document).scrollTop();
101            var $header = $(".main-header");
102            if (st > 200) {
103                $header.addClass('theme-fixed-header');
104            } else {
105                $header.removeClass('theme-fixed-header')
106            }
107        });
108
109        $('#mob-menu').find('.sub-menu,.flat-mega-memu').before('<span class="dropdown-toggle"><strong class="dropdown-icon"></strong>');
110
111        $('#mob-menu').find('.dropdown-toggle').on('click', function(e) {
112            e.preventDefault();
113            $(this).next('.sub-menu,.flat-mega-memu').slideToggle();
114            $(this).toggleClass('toggle-on');
115        });
116
117        // Slick carousel column 1.
118        $(".iteam-col-1.section-carousel-enabled").click({
119            dots: true,
120            infinite: true,
121            slidesToShow: 1,
122            slidesToScroll: 1,
123            dots: false,
124            prevArrow: '<span data-role="none" class="slick-prev" tabindex="0"><i class="fas fa-angle-left" aria-hidden="true"></i></span>',
125            nextArrow: '<span data-role="none" class="slick-next" tabindex="0"><i class="fas fa-angle-right" aria-hidden="true"></i></span>'
126        });
127        // Slick carousel column 2.
128        $(".iteam-col-2.section-carousel-enabled").click({
129            dots: true,
130            infinite: true,
131            slidesToShow: 2,
132            slidesToScroll: 2,
133            dots: false,
134            responsive: [{
135                    breakpoint: 1024,
136                    settings: {
137                        slidesToShow: 1,
138                        slidesToScroll: 1,
139                        infinite: true
140                    }
141                },
142                {
143                    breakpoint: 600,
144                    settings: {
145                        slidesToShow: 1,
146                        slidesToScroll: 1
147                    }
148                }
149            ],
150            prevArrow: '<span data-role="none" class="slick-prev" tabindex="0"><i class="fas fa-angle-left" aria-hidden="true"></i></span>',
151            nextArrow: '<span data-role="none" class="slick-next" tabindex="0"><i class="fas fa-angle-right" aria-hidden="true"></i></span>'
152        });
153
154        // Slick carousel column 3.
155        $(".iteam-col-3.section-carousel-enabled").click({
156            dots: true,
157            infinite: true,
158            slidesToShow: 3,
159            slidesToScroll: 3,
160            dots: false,
161            responsive: [{
162                    breakpoint: 1024,
163                    settings: {
164                        slidesToShow: 2,
165                        slidesToScroll: 2,
166                        infinite: true
167                    }
168                },
169                {
170                    breakpoint: 600,
171                    settings: {
172                        slidesToShow: 1,
173                        slidesToScroll: 1
174                    }
175                }
176            ],
177            prevArrow: '<span data-role="none" class="slick-prev" tabindex="0"><i class="fa fa-angle-left" aria-hidden="true"></i></span>',
178            nextArrow: '<span data-role="none" class="slick-next" tabindex="0"><i class="fa fa-angle-right" aria-hidden="true"></i></span>'
179        });
180
181        // Slick carousel column 4
182        $(".iteam-col-4.section-carousel-enabled").click({
183            dots: true,
184            infinite: true,
185            slidesToShow: 4,
186            slidesToScroll: 4,
187            dots: false,
188            responsive: [{
189                    breakpoint: 1024,
190                    settings: {
191                        slidesToShow: 2,
192                        slidesToScroll: 2,
193                        infinite: true
194                    }
195                },
196                {
197                    breakpoint: 600,
198                    settings: {
199                        slidesToShow: 1,
200                        slidesToScroll: 1
201                    }
202                }
203            ],
204            prevArrow: '<span data-role="none" class="slick-prev" tabindex="0"><i class="fa fa-angle-left" aria-hidden="true"></i></span>',
205            nextArrow: '<span data-role="none" class="slick-next" tabindex="0"><i class="fa fa-angle-right" aria-hidden="true"></i></span>'
206        });
207
208        // Slick carousel column 5
209        $(".iteam-col-5.section-carousel-enabled").click({
210            dots: true,
211            infinite: true,
212            slidesToShow: 5,
213            slidesToScroll: 5,
214            dots: false,
215            responsive: [{
216                    breakpoint: 1024,
217                    settings: {
218                        slidesToShow: 3,
219                        slidesToScroll: 3,
220                        infinite: true
221                    }
222                },
223                {
224                    breakpoint: 600,
225                    settings: {
226                        slidesToShow: 2,
227                        slidesToScroll: 2
228                    }
229                }
230            ],
231            prevArrow: '<span data-role="none" class="slick-prev" tabindex="0"><i class="fa fa-angle-left" aria-hidden="true"></i></span>',
232            nextArrow: '<span data-role="none" class="slick-next" tabindex="0"><i class="fa fa-angle-right" aria-hidden="true"></i></span>'
233        });
234
235        // Skil bar.
236        jQuery('.skillbar').each(function() {
237            jQuery(this).find('.skillbar-bar').animate({
238                width: jQuery(this).attr('data-percent')
239            }, 3000);
240        });
241
242        // Implement go to top.
243        var $scroll_obj = $('#btn-scrollup');
244        $(window).on('scroll', function() {
245            if ($(this).scrollTop() > 100) {
246                $scroll_obj.fadeIn();
247            } else {
248                $scroll_obj.fadeOut();
249            }
250        });
251
252        $scroll_obj.on('click', function() {
253            $('html, body').animate({
254                scrollTop: 0
255            }, 600);
256            return false;
257        });
258
259
260        $('a[href*="#demosz"]:not([href=""])').on('click', function() {
261            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
262                var target = $(this.hash);
263                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
264                if (target.length) {
265                    $('html, body').animate({
266                        scrollTop: target.offset().top - 0
267                    }, 1000);
268                    return false;
269                }
270            }
271        });
272    });
273
274    // 内容保护功能
275    var ContentProtection = {
276        // 默认配置
277        config: {
278            enabled: false,
279            mode: 'disable_all',
280            message: '内容受到保护,禁止复制!'
281        },
282
283        // 初始化内容保护
284        init: function(options) {
285            // 合并配置
286            if (options) {
287                this.config = $.extend(this.config, options);
288            }
289
290            // 如果未启用,则直接返回
291            if (!this.config.enabled) {
292                return;
293            }
294
295            // 根据保护模式应用相应的功能
296            switch (this.config.mode) {
297                case 'disable_all':
298                    this.disableAll();
299                    break;
300                case 'disable_copy':
301                    this.disableCopy();
302                    break;
303                case 'custom_menu':
304                    this.customMenu();
305                    break;
306                case 'disable_text_copy':
307                    this.disableTextCopy();
308                    break;
309                default:
310                    this.disableAll();
311                    break;
312            }
313        },
314
315        // 完全禁用右键
316        disableAll: function() {
317            var message = this.config.message;
318            
319            // 禁用右键菜单
320            $(document).on('contextmenu', function(e) {
321                e.preventDefault();
322                if (message) {
323                    alert(message);
324                }
325                return false;
326            });
327
328            // 禁用复制
329            this.preventCopy();
330        },
331
332        // 允许右键但禁止复制
333        disableCopy: function() {
334            var message = this.config.message;
335            
336            // 禁用复制功能
337            this.preventCopy();
338        },
339
340        // 自定义右键菜单
341        customMenu: function() {
342            var message = this.config.message;
343            
344            // 禁用默认右键菜单
345            $(document).on('contextmenu', function(e) {
346                e.preventDefault();
347                
348                // 创建自定义右键菜单
349                var customMenu = $('<div class="custom-context-menu"></div>')
350                    .html('<div class="custom-menu-message">' + message + '</div>')
351                    .css({
352                        position: 'fixed',
353                        zIndex: 10000,
354                        background: '#fff',
355                        boxShadow: '0 0 10px rgba(0,0,0,0.2)',
356                        padding: '10px',
357                        borderRadius: '4px',
358                        top: e.pageY + 'px',
359                        left: e.pageX + 'px'
360                    });
361                
362                // 添加到页面
363                $('body').append(customMenu);
364                
365                // 点击其他区域关闭菜单
366                $(document).on('click', function() {
367                    $('.custom-context-menu').remove();
368                });
369                
370                return false;
371            });
372            
373            // 禁用复制
374            this.preventCopy();
375        },
376
377        // 仅禁止复制文本
378        disableTextCopy: function() {
379            // 只禁用复制功能
380            this.preventCopy();
381        },
382
383        // 通用方法:禁止复制
384        preventCopy: function() {
385            var message = this.config.message;
386            
387            // 禁用复制、剪切和选择功能
388            $(document).on('copy paste cut dragstart', function(e) {
389                if (message) {
390                    alert(message);
391                }
392                e.preventDefault();
393                return false;
394            });
395            
396            // 禁用键盘快捷键
397            $(document).on('keydown', function(e) {
398                // Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+S, Ctrl+U, F12
399                if ((e.ctrlKey && (e.keyCode === 67 || e.keyCode === 86 || e.keyCode === 85 || e.keyCode === 88 || e.keyCode === 83)) || e.keyCode === 123) {
400                    if (message) {
401                        alert(message);
402                    }
403                    e.preventDefault();
404                    return false;
405                }
406            });
407            
408            // 禁用选择文本
409            $(document).on('selectstart', function(e) {
410                if (e.target.nodeName !== 'INPUT' && e.target.nodeName !== 'TEXTAREA') {
411                    if (message) {
412                        // 不弹出选择文本的提示,避免过于频繁的提示
413                    }
414                    return false;
415                }
416            });
417        }
418    };
419
420    // 检查是否存在全局配置
421    $(document).ready(function() {
422        // 从全局变量获取配置(后端直接注入)
423        var config = window.contentProtectionConfig || {};
424        
425        // 从meta标签获取配置(如果没有全局变量)
426        if (!config.enabled) {
427            var metaTag = $('meta[name="content-protection"]');
428            if (metaTag.length > 0) {
429                try {
430                    config = JSON.parse(metaTag.attr('content')) || {};
431                } catch(e) {
432                    console.error('内容保护配置解析失败:', e);
433                }
434            }
435        }
436        
437        // 初始化内容保护
438        ContentProtection.init({
439            enabled: config.enabled === 1 || config.enabled === '1' || config.enabled === true,
440            mode: config.mode || 'disable_all',
441            message: config.message || '内容受到保护,禁止复制!'
442        });
443    });
444
445    // 暴露给全局
446    window.ContentProtection = ContentProtection;
447
448})(jQuery);

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.