1// $Id: stickyPanels.js 39997 2026-05-18 08:27:53Z brendon $ 2 3;(function ($) { 4 $.fn.stickyPanels = function (options) { 5 var defaults = { 6 header: false, 7 paginationBar: false, 8 fixedElement: null, 9 targetElement: null, 10 subNavbar: false, 11 }, 12 $selElement = this, 13 stickyPanels = { 14 opt: '', 15 className: '', 16 elHeight: 0, 17 fixHeader: null, 18 fixNav: null, 19 pagingNavBar: 0, 20 stickyHeader: false, 21 stickyNav: false, 22 bottomPosition: 0, 23 toolbarMoreBox: null, 24 initialHeight: 0, 25 lastScrollTop: 0, 26 stickyHeaderSpacer: 0, 27 init: function () { 28 var that = this; 29 that.opt = $.extend(defaults, options); 30 if ($selElement.length) { 31 if (that.opt.header || that.opt.paginationBar) { 32 that.className = $selElement.attr("class"); 33 that.initialHeight = window.visualViewport ? window.visualViewport.height : window.innerHeight; 34 stickyPanels.attachScroll(); 35 } 36 } 37 }, 38 checkProfileDisplay: function () { 39 // find out if the profile dropdown is visible 40 var that = this; 41 if (that.fixHeader != null) { 42 that.stickyHeader = (that.fixHeader.css("display") == "block") ? true : false; 43 } 44 }, 45 checkNavigationDisplay: function () { 46 // find out if the navigation dropdown is visible 47 var that = this; 48 if (that.fixNav != null) { 49 that.fixNav.each(function (index, item) { 50 that.stickyNav = false;
51 if ($(item).css("display") == "block") { 52 that.stickyNav = true; 53 return false; 54 } 55 }); 56 } 57 }, 58 changeFixedPaginBar: function (currentScroll) { 59 // change the pagination bar from pageMode to scrollMode, when scrolling up 60 var that = this; 61 if ($(".scrollMode").length == 0) { 62 that.pagingNavBar = $(".stickyPaginNavBar").offset().top; 63 if (currentScroll < that.pagingNavBar) { 64 $(".pagingNavBar").addClass("stickyFooter").removeClass("pagingNavBar"); 65 } else { 66 $selElement.addClass("pagingNavBar").removeClass("stickyFooter"); 67 } 68 } 69 }, 70 attachScroll: function () { 71 var that = this; 72 73 that.fixHeader = $selElement.find("#header .headerFoldout"); 74 that.fixNav = $selElement.find("#navigation .secondLevelWrapper"); 75 76 if (that.opt.header) { 77 if (that.opt.targetElement != null && that.opt.targetElement.length) { 78 that.bottomPosition = that.opt.targetElement.offset().top + that.opt.targetElement.outerHeight(true); 79 } else { 80 // reset variables if targetElement doesnt match 81 that.opt.subNavbar = false; 82 } 83 } 84 85 window.addEventListener('scroll', function() { 86 var currentScroll = window.pageYOffset || document.documentElement.scrollTop; 87 that.elHeight = $selElement.outerHeight(true) + that.stickyHeaderSpacer; 88 89 // banners that appear above the sticky container, need to calculate the height of these elements 90 that.stickyHeaderSpacer = getExtraStickyHeaderHeight(); 91 92 stickyPanels.checkProfileDisplay(); 93 stickyPanels.checkNavigationDisplay(); 94 95 // Show/hide main navbar 96 if (currentScroll > that.elHeight) { 97 if (currentScroll > that.lastScrollTop) { 98 // Scrolling down 99 if (currentScroll > that.bottomPosition) { 100 if (that.opt.subNavbar) { 101 if (that.opt.header) { 102 if (!that.stickyHeader && !that.stickyNav) { 103 $selElement.css({"transform":'translateY(-100%)'}); 104 } 105 } 106 } else { 107 if (that.opt.targetElement != null && that.opt.targetElement.length) { 108 if (that.opt.header) { 109 if (!that.stickyHeader) { 110 $selElement.find("#loginBox").hide(); 111 $selElement.find("#joinBox").show(); 112 $selElement.find("#languageBox").hide(); 113 } 114 } 115 } else { 116 if (that.opt.header) { 117 if (!that.stickyHeader && !that.stickyNav) { 118 $selElement.css({"transform":'translateY(-100%)'}); 119 } 120 } 121 } 122 } 123 } else { 124 if (that.opt.subNavbar) { 125 if (that.opt.header) { 126 if (!that.stickyHeader && !that.stickyNav) { 127 $selElement.css({"transform":'translateY(-100%)'}); 128 } 129 } 130 } else { 131 if (that.opt.header) { 132 if (!that.stickyHeader) { 133 $selElement.css({"transform":'translateY(-100%)'}); 134 } 135 } 136 } 137 } 138 if (that.opt.paginationBar) { 139 $selElement.addClass(that.className+'Hide').removeClass(that.className+'Show'); 140 } 141 } else if (currentScroll < that.lastScrollTop) { 142 // Scrolling up 143 if (that.opt.header) { 144 if (typeof animationScroll != 'undefined' && animationScroll) { 145 $selElement.css({"transform":'translateY(-100%)'}); 146 } else { 147 $selElement.css({"transform":'translateY(0)'}); 148 } 149 if (currentScroll <= that.bottomPosition) { 150 if (!that.opt.subNavbar) { 151 $selElement.find("#loginBox").show(); 152 $selElement.find("#joinBox").hide(); 153 $selElement.find("#languageBox").show(); 154 } 155 } 156 } else if (that.opt.paginationBar) { 157 $selElement.addClass(that.className+'Show').removeClass(that.className+'Hide'); 158 } 159 } 160 } else { 161 // Always show when near top 162 if (that.opt.header) { 163 $selElement.css({"transform":'translateY(0)'}); 164 if ($('.languageDropdown').length) {
165 $('.languageDropdown').slideUp('fast'); 166 } 167 } 168 } 169 170 // profile minibar behavior 171 if (that.opt.header) { 172 if (that.opt.subNavbar) { 173 if (currentScroll > that.bottomPosition) { 174 if (currentScroll > that.lastScrollTop) { 175 // Scrolling down 176 that.opt.fixedElement.css({"opacity":"1", "pointerEvents":"auto", "transform":'translateY(0)'}); 177 if (that.opt.targetElement != null && that.opt.targetElement.length) { 178 that.toolbarMoreBox = that.opt.targetElement.find('.moreBox'); 179 if (that.toolbarMoreBox.length && that.toolbarMoreBox.is(":visible")) { 180 that.toolbarMoreBox.slideUp(); 181 } 182 } 183 } else { 184 // Scrolling up â position below main navbar 185 that.opt.fixedElement.css({"opacity":"1", "pointerEvents":"auto", "transform":"translateY("+$selElement.outerHeight(true)+"px)"}); 186 } 187 } else { 188 // Hide profile minibar completely 189 that.opt.fixedElement.css({"opacity":"0", "pointerEvents":"none", "transform":'translateY(-100%)'}); 190 if (that.opt.fixedElement.find('.moreBox').length) { 191 that.opt.fixedElement.find('.moreBox').slideUp(); 192 } 193 } 194 } 195 } 196 197 if (!that.opt.header) { 198 // Change the inline pagination bar to fixed for pageMode 199 if (that.opt.paginationBar) { 200 stickyPanels.changeFixedPaginBar(currentScroll); 201 } 202 } 203 204 that.lastScrollTop = currentScroll <= 0 ? 0 : currentScroll; // For iOS bounce fix 205 }); 206 207 // a common issue on mobile browsers when the keyboard appears 208 // position: fixed elements behave unpredictably 209 // because the viewport gets resized to accommodate the keyboard 210 if (that.opt.subNavbar) { 211 if (that.opt.header) { 212 if (that.opt.targetElement != null && that.opt.targetElement.length) { 213 $('input, textarea').bind('blur', function (event) { 214 that.opt.fixedElement.show(); 215 }).bind('focus', function (event) { 216 that.opt.fixedElement.hide(); 217 }); 218 } 219 } 220 } 221 } 222 }; 223 224 $(function () { 225 stickyPanels.init(); 226 }); 227 return this; 228 }; 229}(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.