1/** 2 * Author @ds 3 * 4 */ 5 6/** 7 * Call checkOffsetBottom when user scrolls at an interval - only if .stickyFooter exists in DOM 8 */ 9$(document).scroll(function() { 10 if (elementExist('.stickyFooter')) { 11 if (checkClasslist('group-sticky-first', 'navbar-fixed-top') || checkClasslist('group-sticky-second', 'navbar-fixed-top') || $('.stickyFooter').offset().top + $('.footer-aa').height() <= 12 $('.footer-aa').offset().top - 10) { 13 unsetBottomCustomStickyStyle(); 14 } 15 checkOffset(); 16 } 17}); 18 19/** 20 * Call checkoffsetBottom when stickyFooter 21 */ 22$(".stickyFooter").load(function() { 23 checkOffset(); 24}); 25 26/** 27 * Call checkoffsetBottom when page is loaded since user might be at bottom of page (reload) - only if .stickyFooter exists in DOM 28 */ 29$(document).ready(function() { 30 if (elementExist('.stickyFooter')) { 31 checkOffset(); 32 } 33}); 34 35/** 36 * Check if .stickyFooter overlaps with any footer elements then check if .stickyFooter overlaps with groupNavi 37 */ 38function checkOffset() { 39 if ( 40 checkOverlap(document.querySelector('.stickyFooter'), document.querySelector('.footer-aa')) || 41 checkOverlap(document.querySelector('.stickyFooter'), document.querySelector('.footer-group')) || 42 checkOverlap(document.querySelector('.stickyFooter'), document.querySelector('.footer-end')) || 43 checkInside(document.querySelector('.stickyFooter'), document.querySelector('.footer-aa')) || 44 checkInside(document.querySelector('.stickyFooter'), document.querySelector('.footer-group')) || 45 checkInside(document.querySelector('.stickyFooter'), document.querySelector('.footer-end')) 46 ) { 47 setBottomCustomStickyStyle(); 48 } else if ( 49 checkOverlap(document.querySelector('.stickyFooter'), document.querySelector('.groupNavi')) || 50 checkInside(document.querySelector('.stickyFooter'), document.querySelector('.groupNavi')) 51 ) { 52 setTopCustomStickyStyle(); 53 } 54} 55 56/** 57 * Calculate position above footer and sets stickyFooter above it 58 */ 59function setBottomCustomStickyStyle() { 60 const footerPos = document.querySelector('.footer-aa'); 61 const stickyHeight = document.querySelector('.stickyFooter'); 62 let posBottom = ((getOffset(footerPos).top + window.scrollY) - (stickyHeight.offsetHeight + 1.5)) + 'px'; 63 $('.stickyFooter').css('position', 'absolute'); 64 $('.stickyFooter').css('top', posBottom); 65} 66 67/** 68 * Calculate groupNavi height and sets stickyFooter below it 69 */ 70function setTopCustomStickyStyle() { 71 const groupNavi = document.querySelector('.groupNavi'); 72 // let posTop = getOffset(groupNavi).bottom + 'px'; 73 let posTop = groupNavi.clientHeight + 'px'; 74 $('.stickyFooter').css('position', 'absolute'); 75 $('.stickyFooter').css('top', posTop); 76} 77 78/** 79 * Removes custom style 80 */ 81function unsetBottomCustomStickyStyle() { 82 $('.stickyFooter').removeAttr('style'); 83} 84 85/** 86 * 87 * Checks if either a class or id with element name exists and return bool 88 * @param {*} el 89 * @return {bool} 90 */ 91function elementExist(el) { 92 let classEl = document.querySelector(el); 93 let idEl = document.getElementById(el); 94 if (classEl != null || idEl != null) { 95 return true; 96 } else { 97 return false; 98 } 99} 100 101/** 102 * Returns coordinates of el 103 * @param {*} el 104 * @returns {array} 105 */ 106function getOffset(el) { 107 const elementBounding = el.getBoundingClientRect(); 108 return { 109 left: elementBounding.left, 110 top: elementBounding.top, 111 right: elementBounding.right, 112 bottom: elementBounding.bottom 113 }; 114} 115 116/** 117 * Checks if className is in els classList 118 * @param {*} el 119 * @param {*} className 120 * @returns {bool} 121 */ 122function checkClasslist(el, className) { 123 const elementName = document.getElementById(el); 124 return elementName.classList.contains(className); 125} 126 127/** 128 * Check is two elements are overlapping 129 * @param {*} firstElem 130 * @param {*} secondElem 131 * @returns {bool} 132 */ 133function checkOverlap(firstElem, secondElem) { 134 const firstElemOffset = getOffset(firstElem); 135 const secondElemOffset = getOffset(secondElem); 136 return !( 137 firstElemOffset.right < secondElemOffset.left || 138 firstElemOffset.left > secondElemOffset.right || 139 firstElemOffset.bottom < secondElemOffset.top || 140 firstElemOffset.top > secondElemOffset.bottom 141 ); 142} 143 144/** 145 * Checks if one element is insise another 146 * @param {*} firstElem 147 * @param {*} secondElem 148 * @returns {bool} 149 */ 150function checkInside(firstElem, secondElem) { 151 const firstElemOffset = getOffset(firstElem); 152 const secondElemOffset = getOffset(secondElem); 153 return ( 154 firstElemOffset.top <= secondElemOffset.bottom && 155 firstElemOffset.bottom >= secondElemOffset.top && 156 firstElemOffset.left <= secondElemOffset.right && 157 firstElemOffset.right >= secondElemOffset.left 158 ); 159}
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.