1'use strict'; 2 3NodeList.prototype.forEach = Array.prototype.forEach; 4 5function isElInView(el, fullyInView) { 6 var elTop = el.getBoundingClientRect().top; 7 var elBottom = el.getBoundingClientRect().bottom; 8 var winHeight = window.innerHeight; 9 10 if (fullyInView) { 11 return elTop >= 0 && elBottom <= winHeight; 12 } 13 return elTop <= winHeight; 14} 15 16function getPageHeight() { 17 var body = document.body; 18 var html = document.documentElement; 19 20 return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); 21} 22 23function getScrollPos() { 24 var body = document.body; 25 var html = document.documentElement; 26 27 return { 28 yPos: window.pageYOffset || html.scrollTop || body.scrollTop || 0, 29 xPos: window.pageXOffset || html.scrollLeft || body.scrollLeft || 0 30 }; 31} 32 33function stickyCTA() { 34 var defaults = {}; 35 var dom = {}; 36 37 function cacheData(entry) { 38 dom.footer = document.querySelector('.footer-upper'); 39 if (dom.footer) dom.footerPos = getPageHeight() - dom.footer.getBoundingClientRect().height; 40 dom.bottomCTA = document.querySelector('.main-footer'); 41 if (dom.bottomCTA) dom.bottomCTAPos = getPageHeight() - (dom.footer.getBoundingClientRect().height + dom.bottomCTA.getBoundingClientRect().height) - 67 + 'px'; 42 dom.stickyCTA = document.querySelector('.js-sticky-cta'); 43 dom.stickyCTABCR = dom.stickyCTA.getBoundingClientRect(); 44 defaults.enter = getPageHeight() * entry.enter; 45 defaults.exit = getPageHeight() * entry.exit; 46 } 47 48 function modifyFooter() { 49 var lowerPos = dom.bottomCTAPos || dom.footerPos; 50 if (lowerPos < defaults.exit) { 51 if (dom.bottomCTA) { 52 dom.bottomCTA.style.marginTop = dom.stickyCTABCR.height - 1 + 'px'; 53 } else { 54 dom.footer.style.marginTop = dom.stickyCTABCR.height - 1 + 'px'; 55 } 56 defaults.exit += dom.stickyCTABCR.height; 57 } 58 } 59 60 function anchorEl(el, top) { 61 var elHeight = Math.max(el.clientHeight, el.offsetHeight, el.scrollHeight); 62 el.classList.remove('is-sticky'); 63 el.classList.add('is-stuck'); 64 el.style.setProperty('top', top - elHeight + 1 + 'px'); 65 } 66 67 function releaseEl(el) { 68 el.classList.remove('is-stuck'); 69 el.classList.add('is-sticky'); 70 el.style.setProperty('top', ''); 71 } 72 73 function showCta() { 74 if (!dom.stickyCTA.classList.contains('is-visible')) { 75 dom.stickyCTA.classList.add('is-visible'); 76 } 77 } 78 79 function hideCta() { 80 if (dom.stickyCTA.classList.contains('is-visible')) { 81 dom.stickyCTA.classList.remove('is-visible'); 82 } 83 } 84 85 function checkVis() { 86 var html = document.body; 87 if (defaults.enter <= getScrollPos().yPos + window.innerHeight) { 88 showCta(); 89 } 90 if (defaults.exit < getScrollPos().yPos || getScrollPos().yPos + window.innerHeight < defaults.enter) { 91 hideCta(); 92 } 93 var lowerEl = dom.bottomCTA || dom.footer; 94 95 if (!lowerEl) return; 96 97 if (isElInView(lowerEl)) { 98 anchorEl(dom.stickyCTA, lowerEl.offsetTop); 99 } else { 100 releaseEl(dom.stickyCTA); 101 } 102 } 103 104 function setEvents() { 105 window.addEventListener('scroll', checkVis, false); 106 } 107 108 function init() { 109 var entry = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { enter: 0, exit: 1 }; 110 111 cacheData(entry); 112 if (dom.bottomCTA || dom.footer) modifyFooter(); 113 checkVis(); 114 setEvents(); 115 } 116 117 return { 118 init: init 119 }; 120} 121 122window.sticky = stickyCTA();
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.