PHP Classes

File: js/scrollbar.js

Recommend this page to a friend!
  Classes of Subin Siby  >  PHP HTML Compressor  >  js/scrollbar.js  >  Download  
File: js/scrollbar.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP HTML Compressor
Compress Web pages HTML, CSS and JavaScript
Author: By
Last change: Update of js/scrollbar.js
Date: 1 month ago
Size: 26,279 bytes
 

Contents

Class file image Download
/** * jQuery CSS Customizable Scrollbar * * Copyright 2014, Yuriy Khabarov * Dual licensed under the MIT or GPL Version 2 licenses. * * If you found bug, please contact me via email <13real008@gmail.com> * * @author Yuriy Khabarov aka Gromo * @version 0.2.2 * @url https://github.com/gromo/jquery.scrollbar/ * * TODO: * */ ; (function($, doc, win){ // Init flags & variables var browser = { "mobile": /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(win.navigator.userAgent), "webkit": win.WebKitPoint ? true : false, "log": function(data, toString){ var output = data; if(toString && typeof data != "string"){ output = []; $.each(data, function(i, v){ output.push('"' + i + '": ' + v); }); output = output.join(", "); } if(win.console && win.console.log){ win.console.log(output); } }, "scroll": null }; var debug = false; var lmb = 1, px = "px"; var scrolls = []; var defaults = { "autoScrollSize": true, // automatically calculate scrollsize "autoUpdate": true, // update scrollbar if content/container size changed "disableBodyScroll": false, // disable body scroll if mouse over container "duration": 200, // scroll animate duration in ms "ignoreMobile": true, // ignore mobile devices "scrollStep": 30, // scroll step for scrollbar arrows "showArrows": false, // add class to show arrows "stepScrolling": true, // when scrolling to scrollbar mousedown position "type":"simple", // [advanced|simple] scrollbar html type "scrollx": null, // horizontal scroll element "scrolly": null, // vertical scroll element "onDestroy": null, // callback function on destroy, "onInit": null, // callback function on first initialization "onUpdate": null // callback function on init/resize (before scrollbar size calculation) }; var customScrollbar = function(container, options){ if(!browser.scroll){ debug && browser.log("Init jQuery Scrollbar v0.2.1"); browser.scroll = getBrowserScrollSize(); } this.container = container; this.options = $.extend({}, defaults); this.scrollTo = null; this.scrollx = {}; this.scrolly = {}; this.init(options); }; customScrollbar.prototype = { destroy: function(){ if(!this.wrapper){ return; } // init variables var scrollLeft = this.container.scrollLeft(); var scrollTop = this.container.scrollTop(); this.container.insertBefore(this.wrapper).css({ "height":"", "margin":"" }) .removeClass("scroll-content") .removeClass("scroll-scrollx_visible") .removeClass("scroll-scrolly_visible") .off(".scrollbar") .scrollLeft(scrollLeft) .scrollTop(scrollTop); this.scrollx.scrollbar.removeClass("scroll-scrollx_visible").find("div").andSelf().off(".scrollbar"); this.scrolly.scrollbar.removeClass("scroll-scrolly_visible").find("div").andSelf().off(".scrollbar"); this.wrapper.remove(); $(doc).add("body").off(".scrollbar"); if($.isFunction(this.options.onDestroy)) this.options.onDestroy.apply(this, [this.container]); }, getScrollbar: function(d){ var scrollbar = this.options["scroll" + d]; var html = { "advanced": '<div class="scroll-element_corner"></div>' + '<div class="scroll-arrow scroll-arrow_less"></div>' + '<div class="scroll-arrow scroll-arrow_more"></div>' + '<div class="scroll-element_outer">' + ' <div class="scroll-element_size"></div>' + // required! used for scrollbar size calculation ! ' <div class="scroll-element_inner-wrapper">' + ' <div class="scroll-element_inner scroll-element_track">' + // used for handling scrollbar click ' <div class="scroll-element_inner-bottom"></div>' + ' </div>' + ' </div>' + ' <div class="scroll-bar">' + ' <div class="scroll-bar_body">' + ' <div class="scroll-bar_body-inner"></div>' + ' </div>' + ' <div class="scroll-bar_bottom"></div>' + ' <div class="scroll-bar_center"></div>' + ' </div>' + '</div>', "simple": '<div class="scroll-element_outer">' + ' <div class="scroll-element_size"></div>' + // required! used for scrollbar size calculation ! ' <div class="scroll-element_track"></div>' + // used for handling scrollbar click ' <div class="scroll-bar"></div>' + '</div>' }; var type = html[this.options.type] ? this.options.type : "advanced"; if(scrollbar){ if(typeof(scrollbar) == "string"){ scrollbar = $(scrollbar).appendTo(this.wrapper); } else { scrollbar = $(scrollbar); } } else { scrollbar = $("<div>").addClass("scroll-element").html(html[type]).appendTo(this.wrapper); } if(this.options.showArrows){ scrollbar.addClass("scroll-element_arrows_visible"); } return scrollbar.addClass("scroll-" + d); }, init: function(options){ // init variables var S = this; var c = this.container; var o = $.extend(this.options, options); var s = { "x": this.scrollx, "y": this.scrolly }; var w = this.wrapper; var initScroll = { "scrollLeft": c.scrollLeft(), "scrollTop": c.scrollTop() }; // ignore mobile if(browser.mobile && o.ignoreMobile){ return false; } // init scroll container if(!w){ this.wrapper = w = c.wrap($("<div>").css({ "position": (c.css("position") == "absolute") ? "absolute" : "relative" }).addClass("scroll-wrapper").addClass(c.attr("class"))).parent(); c.addClass("scroll-content").css({ "height":"", "margin-bottom": browser.scroll.height * -1 + px, "margin-right": browser.scroll.width * -1 + px }).on("scroll.scrollbar", function(){ s.x.isVisible && s.x.scroller.css("left", c.scrollLeft() * s.x.kx + px); s.y.isVisible && s.y.scroller.css("top", c.scrollTop() * s.y.kx + px); }); /* prevent native scrollbars to be visible on #anchor click */ w.on("scroll", function(){ w.scrollTop(0).scrollLeft(0); }); if(o.disableBodyScroll){ var handleMouseScroll = function(event){ isVerticalScroll(event) ? s.y.isVisible && s.y.mousewheel(event) : s.x.isVisible && s.x.mousewheel(event); }; w.on({ "MozMousePixelScroll.scrollbar": handleMouseScroll, "mousewheel.scrollbar": handleMouseScroll }); if(browser.mobile){ w.on("touchstart.scrollbar", function(event){ var touch = event.originalEvent.touches && event.originalEvent.touches[0] || event; var originalTouch = { "pageX": touch.pageX, "pageY": touch.pageY }; var originalScroll = { "left": c.scrollLeft(), "top": c.scrollTop() }; $(doc).on({ "touchmove.scrollbar": function(event){ var touch = event.originalEvent.targetTouches && event.originalEvent.targetTouches[0] || event; c.scrollLeft(originalScroll.left + originalTouch.pageX - touch.pageX); c.scrollTop(originalScroll.top + originalTouch.pageY - touch.pageY); event.preventDefault(); }, "touchend.scrollbar": function(){ $(doc).off(".scrollbar"); } }); }); } } if($.isFunction(o.onInit)) o.onInit.apply(this, [c]); } else { c.css({ "height":"" }); } // init scrollbars & recalculate sizes $.each(s, function(d, scrollx){ var scrollCallback = null; var scrollForward = 1; var scrollOffset = (d == "x") ? "scrollLeft" : "scrollTop"; var scrollStep = o.scrollStep; var scrollTo = function(){ var currentOffset = c[scrollOffset](); c[scrollOffset](currentOffset + scrollStep); if(scrollForward == 1 && (currentOffset + scrollStep) >= scrollToValue) currentOffset = c[scrollOffset](); if(scrollForward == -1 && (currentOffset + scrollStep) <= scrollToValue) currentOffset = c[scrollOffset](); if(c[scrollOffset]() == currentOffset && scrollCallback){ scrollCallback(); } } var scrollToValue = 0; if(!scrollx.scrollbar){ scrollx.scrollbar = S.getScrollbar(d); scrollx.scroller = scrollx.scrollbar.find(".scroll-bar"); scrollx.mousewheel = function(event){ if(!scrollx.isVisible || (d == 'x' && isVerticalScroll(event))){ return true; } if(d == 'y' && !isVerticalScroll(event)){ s.x.mousewheel(event); return true; } var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail; var maxScrollValue = scrollx.size - scrollx.visible - scrollx.offset; if(!((scrollToValue <= 0 && delta < 0) || (scrollToValue >= maxScrollValue && delta > 0))){ scrollToValue = scrollToValue + delta; if(scrollToValue < 0) scrollToValue = 0; if(scrollToValue > maxScrollValue) scrollToValue = maxScrollValue; S.scrollTo = S.scrollTo || {}; S.scrollTo[scrollOffset] = scrollToValue; setTimeout(function(){ if(S.scrollTo){ c.stop().animate(S.scrollTo, 240, 'linear', function(){ scrollToValue = c[scrollOffset](); }); S.scrollTo = null; } }, 1); } event.preventDefault(); return false; }; scrollx.scrollbar.on({ "MozMousePixelScroll.scrollbar": scrollx.mousewheel, "mousewheel.scrollbar": scrollx.mousewheel, "mouseenter.scrollbar": function(){ scrollToValue = c[scrollOffset](); } }); // handle arrows & scroll inner mousedown event scrollx.scrollbar.find(".scroll-arrow, .scroll-element_track") .on("mousedown.scrollbar", function(event){ if(event.which != lmb) return true; scrollForward = 1; var data = { "eventOffset": event[(d == "x") ? "pageX" : "pageY"], "maxScrollValue": scrollx.size - scrollx.visible - scrollx.offset, "scrollbarOffset": scrollx.scroller.offset()[(d == "x") ? "left" : "top"], "scrollbarSize": scrollx.scroller[(d == "x") ? "outerWidth" : "outerHeight"]() }; var timeout = 0, timer = 0; if($(this).hasClass('scroll-arrow')){ scrollForward = $(this).hasClass("scroll-arrow_more") ? 1 : -1; scrollStep = o.scrollStep * scrollForward; scrollToValue = scrollForward > 0 ? data.maxScrollValue : 0; } else { scrollForward = (data.eventOffset > (data.scrollbarOffset + data.scrollbarSize) ? 1 : (data.eventOffset < data.scrollbarOffset ? -1 : 0)); scrollStep = Math.round(scrollx.visible * 0.75) * scrollForward; scrollToValue = (data.eventOffset - data.scrollbarOffset - (o.stepScrolling ? (scrollForward == 1 ? data.scrollbarSize : 0) : Math.round(data.scrollbarSize / 2))); scrollToValue = c[scrollOffset]() + (scrollToValue / scrollx.kx); } S.scrollTo = S.scrollTo || {}; S.scrollTo[scrollOffset] = o.stepScrolling ? c[scrollOffset]() + scrollStep : scrollToValue; if(o.stepScrolling){ scrollCallback = function(){ scrollToValue = c[scrollOffset](); clearInterval(timer); clearTimeout(timeout); timeout = 0; timer = 0; }; timeout = setTimeout(function(){ timer = setInterval(scrollTo, 40); }, o.duration + 100); } setTimeout(function(){ if(S.scrollTo){ c.animate(S.scrollTo, o.duration); S.scrollTo = null; } }, 1); return handleMouseDown(scrollCallback, event); }); // handle scrollbar drag'n'drop scrollx.scroller.on("mousedown.scrollbar", function(event){ if(event.which != lmb) return true; var eventPosition = event[(d == "x")? "pageX" : "pageY"]; var initOffset = c[scrollOffset](); scrollx.scrollbar.addClass("scroll-draggable"); $(doc).on("mousemove.scrollbar", function(event){ var diff = parseInt((event[(d == "x")? "pageX" : "pageY"] - eventPosition) / scrollx.kx, 10); c[scrollOffset](initOffset + diff); }); return handleMouseDown(function(){ scrollx.scrollbar.removeClass("scroll-draggable"); scrollToValue = c[scrollOffset](); }, event); }); } }); // remove classes & reset applied styles $.each(s, function(d, scrollx){ var scrollClass = "scroll-scroll" + d + "_visible"; var scrolly = (d == "x") ? s.y : s.x; scrollx.scrollbar.removeClass(scrollClass); scrolly.scrollbar.removeClass(scrollClass); c.removeClass(scrollClass); }); // calculate init sizes $.each(s, function(d, scrollx){ $.extend(scrollx, (d == "x") ? { "offset": parseInt(c.css("left"), 10) || 0, "size": c.prop("scrollWidth"), "visible": w.width() } : { "offset": parseInt(c.css("top"), 10) || 0, "size": c.prop("scrollHeight"), "visible": w.height() }); }); var updateScroll = function(d, scrollx){ var scrollClass = "scroll-scroll" + d + "_visible"; var scrolly = (d == "x") ? s.y : s.x; var offset = parseInt(c.css((d == "x") ? "left" : "top"), 10) || 0; var AreaSize = scrollx.size; var AreaVisible = scrollx.visible + offset; scrollx.isVisible = (AreaSize - AreaVisible) > 1; // bug in IE9/11 with 1px diff if(scrollx.isVisible){ scrollx.scrollbar.addClass(scrollClass); scrolly.scrollbar.addClass(scrollClass); c.addClass(scrollClass); } else { scrollx.scrollbar.removeClass(scrollClass); scrolly.scrollbar.removeClass(scrollClass); c.removeClass(scrollClass); } if(d == "y" && (scrollx.isVisible || scrollx.size < scrollx.visible)){ c.css("height", (AreaVisible + browser.scroll.height) + px); } if(s.x.size != c.prop("scrollWidth") || s.y.size != c.prop("scrollHeight") || s.x.visible != w.width() || s.y.visible != w.height() || s.x.offset != (parseInt(c.css("left"), 10) || 0) || s.y.offset != (parseInt(c.css("top"), 10) || 0) ){ $.each(s, function(d, scrollx){ $.extend(scrollx, (d == "x") ? { "offset": parseInt(c.css("left"), 10) || 0, "size": c.prop("scrollWidth"), "visible": w.width() } : { "offset": parseInt(c.css("top"), 10) || 0, "size": c.prop("scrollHeight"), "visible": w.height() }); }); updateScroll(d == "x" ? "y" : "x", scrolly); } }; $.each(s, updateScroll); if($.isFunction(o.onUpdate)) o.onUpdate.apply(this, [c]); // calculate scroll size $.each(s, function(d, scrollx){ var cssOffset = (d == "x") ? "left" : "top"; var cssFullSize = (d == "x") ? "outerWidth" : "outerHeight"; var cssSize = (d == "x") ? "width" : "height"; var offset = parseInt(c.css(cssOffset), 10) || 0; var AreaSize = scrollx.size; var AreaVisible = scrollx.visible + offset; var scrollSize = scrollx.scrollbar.find(".scroll-element_size"); scrollSize = scrollSize[cssFullSize]() + (parseInt(scrollSize.css(cssOffset), 10) || 0); if(o.autoScrollSize){ scrollx.scrollbarSize = parseInt(scrollSize * AreaVisible / AreaSize, 10); scrollx.scroller.css(cssSize, scrollx.scrollbarSize + px); } scrollx.scrollbarSize = scrollx.scroller[cssFullSize](); scrollx.kx = ((scrollSize - scrollx.scrollbarSize) / (AreaSize - AreaVisible)) || 1; }); c.scrollLeft(initScroll.scrollLeft).scrollTop(initScroll.scrollTop).trigger("scroll"); } }; /* * Extend jQuery as plugin * * @param {object|string} options or command to execute * @param {object|array} args additional arguments as array [] */ $.fn.scrollbar = function(options, args){ var toReturn = this; if(options === "get") toReturn = null; this.each(function() { var container = $(this); if(container.hasClass("scroll-wrapper") || container.get(0).nodeName == "body"){ return true; } var instance = container.data("scrollbar"); if(instance){ if(options === "get"){ toReturn = instance; return false; } var func = (typeof options == "string" && instance[options]) ? options : "init"; instance[func].apply(instance, $.isArray(args) ? args : []); if(options === "destroy"){ container.removeData("scrollbar"); while($.inArray(instance, scrolls) >= 0) scrolls.splice($.inArray(instance, scrolls), 1); } } else { if(typeof options != "string"){ instance = new customScrollbar(container, options); container.data("scrollbar", instance); scrolls.push(instance); } } return true; }); return toReturn; }; /** * Connect default options to global object */ $.fn.scrollbar.options = defaults; /** * Check if scroll content/container size is changed */ var timerCounter = 0; var timer = setInterval(function(){ var i, c, o, s, w, x, y; for(i=0; i<scrolls.length; i++){ s = scrolls[i]; c = s.container; o = s.options; w = s.wrapper; x = s.scrollx; y = s.scrolly; if(o.autoUpdate && w && w.is(":visible") && (c.prop("scrollWidth") != x.size || c.prop("scrollHeight") != y.size || w.width() != x.visible || w.height() != y.visible )){ s.init(); if(debug){ browser.log({ "scrollHeight": c.prop("scrollHeight") + ":" + s.scrolly.size, "scrollWidth": c.prop("scrollWidth") + ":" + s.scrollx.size, "visibleHeight": w.height() + ":" + s.scrolly.visible, "visibleWidth": w.width() + ":" + s.scrollx.visible }, true); if(++timerCounter > 10){ browser.log("Scroll updates exceed 10"); clearInterval(timer); } } } } }, 300); /* ADDITIONAL FUNCTIONS */ function getBrowserScrollSize(){ if(browser.webkit){ return { "height": 0, "width": 0 }; } var css = { "border": "none", "height": "100px", "margin": "0", "padding": "0", "width": "100px" }; var inner = $("<div>").css($.extend({}, css)); var outer = $("<div>").css($.extend({ "background": "#F00", "left": "-200px", "overflow": "scroll", "position": "absolute", "top": "-200px" }, css)).append(inner).appendTo("body") .scrollLeft(inner.width()) .scrollTop(inner.height()); var scrollSize = { "height": (outer.offset().top - inner.offset().top) || 0, "width": (outer.offset().left - inner.offset().left) || 0 }; outer.remove(); return scrollSize; } function handleMouseDown(callback, event){ $(doc).on({ "blur.scrollbar": function(){ $(doc).add('body').off('.scrollbar'); callback && callback(); }, "dragstart.scrollbar": function(event){ event.preventDefault(); return false; }, "mouseup.scrollbar": function(){ $(doc).add('body').off('.scrollbar'); callback && callback(); } }); $("body").on({ "selectstart.scrollbar": function(event){ event.preventDefault(); return false; } }); event && event.preventDefault(); return false; } function isVerticalScroll(event){ var e = event.originalEvent; if (e.axis && e.axis === e.HORIZONTAL_AXIS) return false; if (e.wheelDeltaX) return false; return true; } })(jQuery, document, window);