From 93f3664c8846d3cb5268ca678e47713c1826bfcf Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Oct 2016 23:04:26 +0800 Subject: Add missing vendor code hard to deal with --- public/vendor/jquery-scrollspy.js | 267 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 public/vendor/jquery-scrollspy.js (limited to 'public/vendor/jquery-scrollspy.js') diff --git a/public/vendor/jquery-scrollspy.js b/public/vendor/jquery-scrollspy.js new file mode 100644 index 00000000..4fd4f53a --- /dev/null +++ b/public/vendor/jquery-scrollspy.js @@ -0,0 +1,267 @@ +/* + * jQuery ScrollSpy Plugin + * Author: @sxalexander, softwarespot + * Licensed under the MIT license + */ +(function jQueryScrollspy(window, $) { + // Plugin Logic + + $.fn.extend({ + scrollspy: function scrollspy(options, action) { + // If the options parameter is a string, then assume it's an 'action', therefore swap the parameters around + if (_isString(options)) { + var tempOptions = action; + + // Set the action as the option parameter + action = options; + + // Set to be the reference action pointed to + options = tempOptions; + } + + // override the default options with those passed to the plugin + options = $.extend({}, _defaults, options); + + // sanitize the following option with the default value if the predicate fails + _sanitizeOption(options, _defaults, 'container', _isObject); + + // cache the jQuery object + var $container = $(options.container); + + // check if it's a valid jQuery selector + if ($container.length === 0) { + return this; + } + + // sanitize the following option with the default value if the predicate fails + _sanitizeOption(options, _defaults, 'namespace', _isString); + + // check if the action is set to DESTROY/destroy + if (_isString(action) && action.toUpperCase() === 'DESTROY') { + $container.off('scroll.' + options.namespace); + return this; + } + + // sanitize the following options with the default values if the predicates fails + _sanitizeOption(options, _defaults, 'buffer', $.isNumeric); + _sanitizeOption(options, _defaults, 'max', $.isNumeric); + _sanitizeOption(options, _defaults, 'min', $.isNumeric); + + // callbacks + _sanitizeOption(options, _defaults, 'onEnter', $.isFunction); + _sanitizeOption(options, _defaults, 'onLeave', $.isFunction); + _sanitizeOption(options, _defaults, 'onLeaveTop', $.isFunction); + _sanitizeOption(options, _defaults, 'onLeaveBottom', $.isFunction); + _sanitizeOption(options, _defaults, 'onTick', $.isFunction); + + if ($.isFunction(options.max)) { + options.max = options.max(); + } + + if ($.isFunction(options.min)) { + options.min = options.min(); + } + + // check if the mode is set to VERTICAL/vertical + var isVertical = window.String(options.mode).toUpperCase() === 'VERTICAL'; + + return this.each(function each() { + // cache this + var _this = this; + + // cache the jQuery object + var $element = $(_this); + + // count the number of times a container is entered + var enters = 0; + + // determine if the scroll is with inside the container + var inside = false; + + // count the number of times a container is left + var leaves = 0; + + // create a scroll listener for the container + $container.on('scroll.' + options.namespace, function onScroll() { + // cache the jQuery object + var $this = $(this); + + // create a position object literal + var position = { + top: $this.scrollTop(), + left: $this.scrollLeft(), + }; + + var containerHeight = $container.height(); + + var max = options.max; + + var min = options.min; + + var xAndY = isVertical ? position.top + options.buffer : position.left + options.buffer; + + if (max === 0) { + // get the maximum value based on either the height or the outer width + max = isVertical ? containerHeight : $container.outerWidth() + $element.outerWidth(); + } + + // if we have reached the minimum bound, though are below the max + if (xAndY >= min && xAndY <= max) { + // trigger the 'scrollEnter' event + if (!inside) { + inside = true; + enters++; + + // trigger the 'scrollEnter' event + $element.trigger('scrollEnter', { + position: position, + }); + + // call the 'onEnter' function + if (options.onEnter !== null) { + options.onEnter(_this, position); + } + } + + // trigger the 'scrollTick' event + $element.trigger('scrollTick', { + position: position, + inside: inside, + enters: enters, + leaves: leaves, + }); + + // call the 'onTick' function + if (options.onTick !== null) { + options.onTick(_this, position, inside, enters, leaves); + } + } else { + if (inside) { + inside = false; + leaves++; + + // trigger the 'scrollLeave' event + $element.trigger('scrollLeave', { + position: position, + leaves: leaves, + }); + + // call the 'onLeave' function + if (options.onLeave !== null) { + options.onLeave(_this, position); + } + + if (xAndY <= min) { + // trigger the 'scrollLeaveTop' event + $element.trigger('scrollLeaveTop', { + position: position, + leaves: leaves, + }); + + // call the 'onLeaveTop' function + if (options.onLeaveTop !== null) { + options.onLeaveTop(_this, position); + } + } else if (xAndY >= max) { + // trigger the 'scrollLeaveBottom' event + $element.trigger('scrollLeaveBottom', { + position: position, + leaves: leaves, + }); + + // call the 'onLeaveBottom' function + if (options.onLeaveBottom !== null) { + options.onLeaveBottom(_this, position); + } + } + } else { + // Idea taken from: http://stackoverflow.com/questions/5353934/check-if-element-is-visible-on-screen + var containerScrollTop = $container.scrollTop(); + + // Get the element height + var elementHeight = $element.height(); + + // Get the element offset + var elementOffsetTop = $element.offset().top; + + if ((elementOffsetTop < (containerHeight + containerScrollTop)) && (elementOffsetTop > (containerScrollTop - elementHeight))) { + // trigger the 'scrollView' event + $element.trigger('scrollView', { + position: position, + }); + + // call the 'onView' function + if (options.onView !== null) { + options.onView(_this, position); + } + } + } + } + }); + }); + }, + }); + + // Fields (Private) + + // Defaults + + // default options + var _defaults = { + // the offset to be applied to the left and top positions of the container + buffer: 0, + + // the element to apply the 'scrolling' event to (default window) + container: window, + + // the maximum value of the X or Y coordinate, depending on mode the selected + max: 0, + + // the maximum value of the X or Y coordinate, depending on mode the selected + min: 0, + + // whether to listen to the X (horizontal) or Y (vertical) scrolling + mode: 'vertical', + + // namespace to append to the 'scroll' event + namespace: 'scrollspy', + + // call the following callback function every time the user enters the min / max zone + onEnter: null, + + // call the following callback function every time the user leaves the min / max zone + onLeave: null, + + // call the following callback function every time the user leaves the top zone + onLeaveTop: null, + + // call the following callback function every time the user leaves the bottom zone + onLeaveBottom: null, + + // call the following callback function on each scroll event within the min and max parameters + onTick: null, + + // call the following callback function on each scroll event when the element is inside the viewable view port + onView: null, + }; + + // Methods (Private) + + // check if a value is an object datatype + function _isObject(value) { + return $.type(value) === 'object'; + } + + // check if a value is a string datatype with a length greater than zero when whitespace is stripped + function _isString(value) { + return $.type(value) === 'string' && $.trim(value).length > 0; + } + + // check if an option is correctly formatted using a predicate; otherwise, return the default value + function _sanitizeOption(options, defaults, property, predicate) { + // set the property to the default value if the predicate returned false + if (!predicate(options[property])) { + options[property] = defaults[property]; + } + } +}(window, window.jQuery)); -- cgit v1.2.3