1(function () { 2 3 ////////////////////// 4 // Utils 5 ////////////////////// 6 function throttle(fn, delay, scope) { 7 // Default delay 8 delay = delay || 250; 9 var last, defer; 10 return function () { 11 var context = scope || this, 12 now = +new Date(), 13 args = arguments; 14 if (last && now < last + delay) { 15 clearTimeout(defer); 16 defer = setTimeout(function () { 17 last = now; 18 fn.apply(context, args); 19 }, delay); 20 } else { 21 last = now; 22 fn.apply(context, args); 23 } 24 }; 25 } 26 27 function extend(destination, source) { 28 for (var k in source) { 29 if (source.hasOwnProperty(k)) { 30 destination[k] = source[k]; 31 } 32 } 33 return destination; 34 } 35 var ScrollManager = function () { 36 var defaults = { 37 steps: null, 38 navigationContainer: null, 39 links: null, 40 scrollToTopBtn: null, 41 windowPercent: 0.7,//elementåºç°å¨é¡µé¢70%çå°æ¹åæ¢ 42 navigationElementClass: '.Quick-navigation', 43 currentStepClass: 'current', 44 smoothScrollEnabled: true, 45 stepsCheckEnabled: true, 46 // Callbacks 47 onScroll: null, 48 onStepChange: function (step, index) { 49 var self = this; 50 var relativeLink = [].filter.call(options.links, function (link) { 51 link.classList.remove(self.currentStepClass); 52 return link.hash === '#' + step.id; 53 }); 54 55 relativeLink[0] != null && relativeLink[0].classList.add(self.currentStepClass); 56 }, 57 // Provide a default scroll animation 58 smoothScrollAnimation: function (target) { 59 $('html, body').animate({ 60 scrollTop: target 61 }, 62 'slow'); 63 } 64 }, 65 66 67 options = {}; 68 69 // Privates 70 var _animation = null, 71 currentStep = null, 72 throttledGetScrollPosition = null; 73 74 return { 75 scrollPosition: 0, 76 init: function (opts) { 77 options = extend(defaults, opts); 78 if (options.steps === null) { 79 console.warn('Smooth scrolling require some sections or steps to scroll to :)'); 80 return false; 81 } 82 // Allow to customize the animation engine ( jQuery / GSAP / velocity / ... ) 83 _animation = function (target) { 84 target = typeof target === 'number' ? target : $(target).offset().top; 85 return options.smoothScrollAnimation(target); 86 }; 87 88 // Activate smooth scrolling 89 if (options.smoothScrollEnabled) this.smoothScroll(); 90 91 // Scroll to top handling 92 if (options.scrollToTopBtn) { 93 options.scrollToTopBtn.addEventListener('click', function () { 94 options.smoothScrollAnimation(0); 95 }); 96 } 97 98 // Throttle for performances gain 99 throttledGetScrollPosition = throttle(this.getScrollPosition).bind(this); 100 window.addEventListener('scroll', throttledGetScrollPosition); 101 window.addEventListener('resize', throttledGetScrollPosition); 102
103 this.getScrollPosition(); 104 }, 105 106 getScrollPosition: function () { 107 this.scrollPosition = window.pageYOffset || window.scrollY; 108 if (options.stepsCheckEnabled) this.checkActiveStep(); 109 if (typeof options.onScroll === 'function') options.onScroll(this.scrollPosition); 110 }, 111 112 scrollPercentage: function () { 113 var body = document.body, 114 html = document.documentElement, 115 documentHeight = Math.max(body.scrollHeight, body.offsetHeight, 116 html.clientHeight, html.scrollHeight, html.offsetHeight); 117 118 var percentage = Math.round(this.scrollPosition / (documentHeight - window.innerHeight) * 100); 119 if (percentage < 0) percentage = 0; 120 if (percentage > 100) percentage = 100; 121 return percentage; 122 }, 123 124 doSmoothScroll: function (e) { 125 if (e.target.nodeName === 'A') { 126 e.preventDefault(); 127 if (location.pathname.replace(/^\//, '') === e.target.pathname.replace(/^\//, '') && location.hostname === e.target.hostname) { 128 var targetStep = document.querySelector(e.target.hash); 129 targetStep ? _animation(targetStep) : console.warn('Hi! You should give an animation callback function to the Scroller module! :)'); 130 } 131 } 132 }, 133 134 smoothScroll: function () { 135 if (options.navigationContainer !== null) options.navigationContainer.addEventListener('click', this.doSmoothScroll); 136 }, 137 138 checkActiveStep: function () { 139 var scrollPosition = this.scrollPosition; 140 141 [].forEach.call(options.steps, function (step, index) { 142 var bBox = step.getBoundingClientRect(), 143 position = step.offsetTop - $(window).height() * 0.7, 144 height = position + bBox.height; 145 if (scrollPosition >= position && scrollPosition < height && currentStep !== step) { 146 currentStep = step; 147 options.steps.forEach(function (item) { 148 item.classList.remove(defaults.currentStepClass) 149 }) 150 step.classList.add(defaults.currentStepClass); 151 if (typeof options.onStepChange === 'function') options.onStepChange(step, index); 152 } 153 154 //step.classList.remove(defaults.currentStepClass); 155 156 157 }); 158 }, 159 160 destroy: function () { 161 window.removeEventListener('scroll', throttledGetScrollPosition); 162 window.removeEventListener('resize', throttledGetScrollPosition); 163 options.navigationContainer.removeEventListener('click', this.doSmoothScroll); 164 } 165 }; 166 167 }(); 168 169 function pen({ trigger = [], triggerName = [], scrollToTopBtn }) { 170 var scrollToTopBtn = document.querySelector(scrollToTopBtn), 171 steps = [], 172 navigationContainer = document.querySelector('.Quick-navigation'), 173 links = [] 174 trigger.forEach(function (item, index) { 175 steps.push(document.querySelector(item)) 176 const newsEle = document.createElement("a") 177 newsEle.innerText = triggerName[index] 178 newsEle.classList.add("Quick-navigation-item") 179 newsEle.setAttribute("href", "#" + document.querySelector(item).getAttribute("id")) 180 navigationContainer.appendChild(newsEle) 181 links.push(newsEle) 182 }) 183 ScrollManager.init({ 184 steps: steps, 185 scrollToTopBtn: scrollToTopBtn, 186 navigationContainer: navigationContainer, 187 links: links, 188 }); 189 } 190 window.pen = pen 191})(jQuery, window, document);
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.