403Webshell
Server IP : 156.238.232.47  /  Your IP : 216.73.216.150
Web Server : nginx/1.25.3
System : Linux C202504152095410 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User : www ( 1000)
PHP Version : 8.3.25
Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /www/data/wwwroot/2025_11_27_02/skin/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /www/data/wwwroot/2025_11_27_02/skin/js/viewport.js
// Viewport Helper
// --------------------------------------------
//
// * **Class:** Viewport
// * **Version:** 1.0
// * **Modified:** 06/26/2013
// * **Author:** Glen Cheney
// * **Dependencies:** jQuery 1.7+, SONY Settings, throttle/debounce
//
// *Notes:*
//
// If you need to be notified when an element is scrolled into view, use this module.
// This module keeps track of all elements that want to be watched and caches their offsets
// and dimensions in order to keep scrolling as smooth as possible.
//
// *Example Usage:*
//
//      Viewport.add({
//        element: document.getElementById('some-wrapper'),
//        threshold: '50%',
//        enter: function( element ) {
//          console.log('the top of "element" is 50% in view');
//        },
//        leave: function() {
//          console.log('bottom of element has left the viewport');
//        }
//      });
//
// *Viewport.add parameters:*
//
// * `element` is a DOM element and `callback` is a function. `this` in the callback is the element.
// * Using an options object, a `threshold` can be set.
//   It is either an integer value from the bottom of the window, a string percentage, or a float
//   between 0 and 1 which represents the percent.
//

(function($) {

    'use strict';

    var instance = null;
    var $window = $(window);

    var ViewportItem = function(options) {
        var self = this;

        // Get defaults
        $.extend(self, ViewportItem.options, options, ViewportItem.settings);

        // The whole point is to have a callback function.
        // Don't do anything if it's not given
        if (!$.isFunction(self.enter)) {
            throw new TypeError('Viewport.add :: No `enter` function provided in Viewport options.');
        }

        // Threshold can be a percentage. Parse it.
        if ((typeof self.threshold === 'string' && self.threshold.indexOf('%') > -1)) {
            self.isThresholdPercentage = true;
            self.threshold = parseFloat(self.threshold) / 100;

        } else if (self.threshold < 1 && self.threshold > 0) {
            self.isThresholdPercentage = true;
        }

        self.hasLeaveCallback = $.isFunction(self.leave);
        self.$element = $(self.element);

        // Cache element's offsets and dimensions
        self.update();
    };

    ViewportItem.prototype.update = function() {
        var self = this;

        self.offset = self.$element.offset();
        self.height = self.$element.height();
        self.width = self.$element.width();
    };

    ViewportItem.options = {
        threshold: 200,
        delay: 0
    };

    ViewportItem.settings = {
        triggered: false,
        isThresholdPercentage: false
    };

    var Viewport = function() {
        this.init();
    };

    Viewport.prototype = {
        init: function() {
            var self = this;

            self.list = [];
            self.lastScrollY = 0;
            self.windowHeight = $window.height();
            self.windowWidth = $window.width();
            self.throttleTime = 100;

            self.onResize();
            self.bindEvents();

            // What's nice here is that rAF won't execute until the user is on this tab,
            // so if they open the page in a new tab which they aren't looking at,
            // this will execute when they come back to that tab
            self.willProcessNextFrame = true;
            requestAnimationFrame(function() {
                self.setScrollTop();
                self.process();
                self.willProcessNextFrame = false;
            });
        },
        bindEvents: function() {
            var self = this,
                    refresh;

            // Updates offsets after a zero timeout
            refresh = function() {
                setTimeout(function refreshWithDelay() {
                    self.refresh();
                }, 0);
            };

            // Listen for global resize
            $window.on('resize.viewport', $.proxy(self.onResize, self));

            // Throttle scrolling because it doesn't need to be super accurate
            $window.on('scroll.viewport', $.throttle(self.throttleTime, $.proxy(self.onScroll, self)));

            self.hasActiveHandlers = true;
        },
        unbindEvents: function() {
            $window.off('.viewport');

            this.hasActiveHandlers = false;
        },
        maybeUnbindEvents: function() {
            var self = this;

            // Not currently watching anything, unbind events
            if (!self.list.length) {
                self.unbindEvents();
            }
        },
        add: function(viewportItem) {
            var self = this;

            self.list.push(viewportItem);

            // Event handlers are removed if a callback is triggered and the
            // watch list is empty. Because modules are instantiated asynchronously,
            // another module could potentially add itself to the watch list when the events
            // have been unbound.
            // Check here if events have been unbound and bind them again if they have
            if (!self.hasActiveHandlers) {
                self.bindEvents();
            }

            if (!self.willProcessNextFrame) {
                self.willProcessNextFrame = true;
                requestAnimationFrame(function() {
                    self.willProcessNextFrame = false;
                    self.process();
                });
            }
        },
        saveDimensions: function() {
            var self = this;

            $.each(self.list, function(i, viewportItem) {
                viewportItem.update();
            });

            // self.documentHeight
            self.windowHeight = $window.height();
            self.windowWidth = $window.width();
        },
        // Throttled scroll event
        onScroll: function() {
            var self = this;

            // No point in doing anything if there aren't any viewports to watch
            if (!self.list.length) {
                return;
            }

            // Save the new scroll top
            self.setScrollTop();

            self.process();
        },
        // Debounced resize event
        onResize: function() {
            this.refresh();
        },
        refresh: function() {

            // No point in doing anything if there aren't any viewports to watch
            if (!this.list.length) {
                return;
            }

            // Update offsets and width/height for each viewport item
            this.saveDimensions();

        },
        isInViewport: function(viewportItem) {
            var self = this,
                    offset = viewportItem.offset,
                    threshold = viewportItem.threshold,
                    percentage = threshold,
                    st = self.lastScrollY,
                    isTopInView;


            if (viewportItem.isThresholdPercentage) {
                threshold = 0;
            }

            // Other checks could be added here in the future
            isTopInView = self.isTopInView(st, self.windowHeight, offset.top, viewportItem.height, threshold);

            // If the top isn't in view with zero threshold,
            // don't bother checking if it's at a percent of the window
            if (isTopInView && viewportItem.isThresholdPercentage) {
                isTopInView = self.isTopPastPercent(st, self.windowHeight, offset.top, viewportItem.height, percentage);
            }

            return isTopInView;
        },
        // If  the top of the element (plus the threshold) is past the viewport's top
        // and the top of the element (plus the threshold) is not past the viewport's bottom.
        // Then the top is in view.
        isTopInView: function(viewportTop, viewportHeight, elementTop, elementHeight, threshold) {
            var viewportBottom = viewportTop + viewportHeight;
            return (elementTop + threshold) >= viewportTop && (elementTop + threshold) < viewportBottom;
        },
        isTopPastPercent: function(viewportTop, viewportHeight, elementTop, elementHeight, percentage) {
            var viewportBottom = viewportTop + viewportHeight,
                    distFromViewportBottomToElementTop = viewportBottom - elementTop,
                    percentFromBottom = distFromViewportBottomToElementTop / viewportHeight;
            return percentFromBottom >= percentage;
        },
        isOutOfViewport: function(viewport, side) {
            var self = this,
                    offset = viewport.offset,
                    st = self.lastScrollY,
                    bool;

            if (side === 'bottom') {
                bool = !self.isBottomInView(st, self.windowHeight, offset.top, viewport.height);
            }

            return bool;
        },
        isBottomInView: function(viewportTop, viewportHeight, elementTop, elementHeight) {
            var viewportBottom = viewportTop + viewportHeight,
                    elementBottom = elementTop + elementHeight;
            return elementBottom > viewportTop && elementBottom <= viewportBottom;
        },
        triggerEnter: function(viewportItem) {
            var self = this;

            // Queue up the callback with the delay. Default is 0
            setTimeout(function() {
                viewportItem.enter.call(viewportItem.element, viewportItem);
            }, viewportItem.delay);


            if ($.isFunction(viewportItem.leave)) {
                viewportItem.triggered = true;

                // If the leave property is not a function,
                // The module no longer needs to watch it, so remove from list
                // However, the list may have been modified already in this loop, so find the
                // index of the viewport item instead of using the loop index.
            } else {
                self.list.splice($.inArray(viewportItem, self.list), 1);
            }

            // If there are no more, unbind from scroll and resize events
            self.maybeUnbindEvents();
        },
        triggerLeave: function(viewportItem) {
            // var self = this;

            // Queue up the callback with the delay. Default is 0
            setTimeout(function() {
                viewportItem.leave.call(viewportItem.element, viewportItem);
            }, viewportItem.delay);

            viewportItem.triggered = false;
        },
        setScrollTop: function() {
            // Save the new scroll top
            this.lastScrollY = $window.scrollTop();
        },
        process: function() {
            var self = this,
                    // The list can possibly be modified mid loop,
                    // so the loop needs a copy of the variable which won't be modified
                    list = $.extend([], self.list);

            $.each(list, function(i, viewportItem) {
                var isInViewport = self.isInViewport(viewportItem),
                        isBottomOutOfView = viewportItem.hasLeaveCallback && self.isOutOfViewport(viewportItem, 'bottom');

                // If the enter callback hasn't been triggerd and it's in the viewport,
                // trigger the enter callback
                if (!viewportItem.triggered && isInViewport) {
                    return self.triggerEnter(viewportItem);
                }

                // This viewport has already come into view once and now it is out of view
                // It's not in view, the bottom is out of view, the list item's enter has been triggered
                if (!isInViewport && isBottomOutOfView && viewportItem.triggered) {
                    return self.triggerLeave(viewportItem);
                }
            });
        }
    };


    Viewport.add = function(options) {
        var instance = Viewport.getInstance();

        return instance.add(new ViewportItem(options));
    };


    Viewport.refresh = function() {
        Viewport.getInstance().refresh();
    };


    Viewport.getInstance = function() {
        if (!instance) {
            instance = new Viewport();
        }

        return instance;
    };


    window.Viewport = Viewport;
}(jQuery));

Youez - 2016 - github.com/yon3zu
LinuXploit