1// scrollArea plugin - create scrollable area in content holder depending on window height 2(function($) { 3 // detect device type 4 var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 5 6 // options 7 function scrollArea(options) { 8 this.options = $.extend({ 9 heightProp: 'height', // which property to use: height or max-height 10 recalcOnPageScroll: false,// recalculate on page scroll (useful when element is not fixed by default) 11 setScrollTo: '', // set scroll to another holder 12 extraSpacing: 0 // subtract extra spacing from scrollable element for correct calculation (margin, padding, border, position). Both manually added or retrieved numbers (with JS) can be used. 13 }, options); 14 15 this.init(); 16 } 17 18 // prototype 19 scrollArea.prototype = { 20 init: function() { 21 var self = this, 22 heightPropVars = ['height', 'max-height', 'maxHeight'], 23 heightPropVarsValid; 24 25 // height properties validation 26 for (var i = 0; i < heightPropVars.length; i++) { 27 if (heightPropVars[i] === self.options.heightProp) { 28 heightPropVarsValid = true; 29 } 30 } 31 32 if (this.options.holder && typeof heightPropVarsValid !== 'undefined') { 33 this.findElements(); 34 this.attachEvents(); 35 this.setHeight(); 36 } 37 }, 38 findElements: function() { 39 this.scrollAreaWrapper = $(this.options.holder); 40 this.scrollArea = !!this.options.setScrollTo ? this.scrollAreaWrapper.find(this.options.setScrollTo) : this.scrollAreaWrapper; // assign scroll area depending on options 41 }, 42 attachEvents: function() { 43 if(this.destroyed) return; 44 45 var self = this, 46 delay = 2000, 47 timeout = null; 48 49 // bind events 50 this.onResize = function() { 51 self.setHeight(); 52 }; 53 this.onScroll = function() { 54 // timeout is needed to eliminate calculation issues on mobile devices (especially iOS), it waits till event has stopped and fires function only after this. Also it helps eliminate multiple event activations, what is good for overall optimization. 55 clearTimeout(timeout); 56 timeout = setTimeout(function() { 57 self.setHeight(); 58 }, delay); 59 }; 60 61 // on mobiles scroll event should be always active to eliminate issue with default browsers slide in/out toolbars 62 if(!!isTouchDevice) { 63 $(window).on('orientationchange', this.onResize); 64 $(window).on('touchend', this.onScroll); 65 } else { 66 // handle events 67 $(window).on('resize', this.onResize); 68 if(this.options.recalcOnPageScroll) { 69 $(window).on('scroll', this.onScroll); 70 } 71 } 72 }, 73 calcHeight: function() { 74 var win = $(window), 75 scrollAreaWrapperOffset = Math.round(this.scrollAreaWrapper.offset().top), 76 winHeight = typeof window.innerHeight ? window.innerHeight : win.height(), 77 winScrollTop = win.scrollTop(); 78 this.scrollAreaWrapperHeight = 0; 79 80 if(scrollAreaWrapperOffset >= winScrollTop) { 81 this.scrollAreaWrapperHeight = winHeight - (scrollAreaWrapperOffset - winScrollTop) - this.options.extraSpacing; 82 } else { 83 this.scrollAreaWrapperHeight = winHeight - (scrollAreaWrapperOffset - this.options.extraSpacing); 84 } 85 }, 86 setHeight: function() { 87 if(this.destroyed) return; 88 89 this.calcHeight(); 90 this.scrollArea.css(this.options.heightProp, this.scrollAreaWrapperHeight); 91 this.scrollArea.css('overflow', 'auto'); 92 }, 93 destroy: function() { 94 var self = this; 95 self.destroyed = true; 96 97 // destroy handler 98 if(!!isTouchDevice) { 99 $(window).off('orientationchange', this.onResize); 100 $(window).off('touchend', this.onScroll); 101 } else { 102 // handle events 103 $(window).off('resize', this.onResize); 104 if(this.options.recalcOnPageScroll) { 105 $(window).off('scroll', this.onScroll); 106 } 107 } 108 // remove assigned styles 109 this.scrollArea.css(this.options.heightProp, ''); 110 this.scrollArea.css('overflow', ''); 111 // remove data 112 this.scrollAreaWrapper.removeData('scrollArea'); 113 } 114 }; 115 116 // jquery plugin 117 $.fn.scrollArea = function(opt){ 118 return this.each(function(){ 119 $(this).data('scrollArea', new scrollArea($.extend(opt, {holder: this}))); 120 }); 121 }; 122})(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.