http://www.kaiu.net/effectCon.aspx?id=2198
<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery右侧悬浮楼层滚动代码 - 开优网络</title> <script type="text/javascript" src="js/jquery.min.js"></script> <style> html { box-sizing: border-box; } *, *:after, *:before { box-sizing: inherit; } html, body { height: 100%; } body { font-family: "Roboto", Helvetica, Arial, sans-serif; margin: 0; } h1 { margin: 0; padding: 0; } section { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; align-items: center; color: rgba(0,0,0,0.5); font-size: 2rem; min-height: 100%; height: 100vh; } .Quick-navigation { position: fixed; z-index: 1; margin: 0; top: 50%; right: 0; -webkit-transform: translateY(-50%); transform: translateY(-50%); } .Quick-navigation-item { color: rgba(0,0,0,0.4); text-decoration: none; font-size: 1.3em; -webkit-transition: color 0.3s; transition: color 0.3s; padding: 0.5em; display: block; } .Quick-navigation-item:hover, .Quick-navigation-item.current { color: #fff; } .Scroll-progress-indicator { will-change: opacity, transform; -webkit-transition: all 0.5s; transition: all 0.5s; left: -10px; border-radius: 2px; position: absolute; top: 50%; opacity: 0; padding: 2em; -webkit-transform: translateX(200%) translateY(-50%); transform: translateX(200%) translateY(-50%); background-color: rgba(0,0,0,0.1); } .Scroll-progress-indicator.visible { -webkit-transform: translateX(-100%) translateY(-50%); transform: translateX(-100%) translateY(-50%); opacity: 1; } #A { background-color: #dc143c; } #B { background-color: #eb2049; height: 600px; } #C { background-color: #ed395d; } #D { background-color: #ef5271; height: 200px; } #E { background-color: #f26a85; } .Scroll-to-top { position: fixed; right: 20px; bottom: 0; background-color: rgba(0,0,0,0.2); border: none; color: rgba(255,255,255,0.5); font-size: 1.5rem; padding: 0.5em; cursor: pointer; opacity: 0; -webkit-transform: translateY(100%); transform: translateY(100%); -webkit-transition: all 0.3s; transition: all 0.3s; outline: none; } .Scroll-to-top.visible { opacity: 1; -webkit-transform: translateY(0); transform: translateY(0); } .Scroll-to-top:hover { color: rgba(255,255,255,0.9); } </style> </head> <body> <nav class="Quick-navigation"> <a href="#A" class="Quick-navigation-item">A</a> <a href="#B" class="Quick-navigation-item">B</a> <a href="#C" class="Quick-navigation-item">C</a> <a href="#D" class="Quick-navigation-item">D</a> <a href="#E" class="Quick-navigation-item">E</a> <div class="Scroll-progress-indicator"></div> </nav> <section id="A" class="js-scroll-step"> <h1>A</h1> </section> <section id="B" class="js-scroll-step"> <h1>B</h1> </section> <section id="C" class="js-scroll-step"> <h1>C</h1> </section> <section id="D" class="js-scroll-step"> <h1>D</h1> </section> <section id="E" class="js-scroll-step"> <h1>E</h1> </section> <button class="Scroll-to-top">Scroll To Top</button> <script> (function () { ////////////////////// // Utils ////////////////////// function throttle(fn, delay, scope) { // Default delay delay = delay || 250; var last, defer; return function () { var context = scope || this, now = +new Date(), args = arguments; if (last && now < last + delay) { clearTimeout(defer); defer = setTimeout(function () { last = now; fn.apply(context, args); }, delay); } else { last = now; fn.apply(context, args); } } } function extend(destination, source) { for (var k in source) { if (source.hasOwnProperty(k)) { destination[k] = source[k]; } } return destination; } ////////////////////// // END Utils ////////////////////// ////////////////////// // Scroll Module ////////////////////// var ScrollManager = (function () { var defaults = { steps: null, navigationContainer: null, links: null, scrollToTopBtn: null, navigationElementClass: ‘.Quick-navigation‘, currentStepClass: ‘current‘, smoothScrollEnabled: true, stepsCheckEnabled: true, // Callbacks onScroll: null, onStepChange: function (step) { var self = this; var relativeLink = [].filter.call(options.links, function (link) { link.classList.remove(self.currentStepClass); return link.hash === ‘#‘ + step.id; }); relativeLink[0].classList.add(self.currentStepClass); }, // Provide a default scroll animation smoothScrollAnimation: function (target) { $(‘html, body‘).animate({ scrollTop: target }, ‘slow‘); } }, options = {}; // Privates var _animation = null, currentStep = null, throttledGetScrollPosition = null; return { scrollPosition: 0, init: function (opts) { options = extend(defaults, opts); if (options.steps === null) { console.warn(‘Smooth scrolling require some sections or steps to scroll to :)‘); return false; } // Allow to customize the animation engine ( jQuery / GSAP / velocity / ... ) _animation = function (target) { target = typeof target === ‘number‘ ? target : $(target).offset().top; return options.smoothScrollAnimation(target); }; // Activate smooth scrolling if (options.smoothScrollEnabled) this.smoothScroll(); // Scroll to top handling if (options.scrollToTopBtn) { options.scrollToTopBtn.addEventListener(‘click‘, function () { options.smoothScrollAnimation(0); }); } // Throttle for performances gain throttledGetScrollPosition = throttle(this.getScrollPosition).bind(this); window.addEventListener(‘scroll‘, throttledGetScrollPosition); window.addEventListener(‘resize‘, throttledGetScrollPosition); this.getScrollPosition(); }, getScrollPosition: function () { this.scrollPosition = window.pageYOffset || window.scrollY; if (options.stepsCheckEnabled) this.checkActiveStep(); if (typeof options.onScroll === ‘function‘) options.onScroll(this.scrollPosition); }, scrollPercentage: function () { var body = document.body, html = document.documentElement, documentHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); var percentage = Math.round(this.scrollPosition / (documentHeight - window.innerHeight) * 100); if (percentage < 0) percentage = 0; if (percentage > 100) percentage = 100; return percentage; }, doSmoothScroll: function (e) { if (e.target.nodeName === ‘A‘) { e.preventDefault(); if (location.pathname.replace(/^\//, ‘‘) === e.target.pathname.replace(/^\//, ‘‘) && location.hostname === e.target.hostname) { var targetStep = document.querySelector(e.target.hash); targetStep ? _animation(targetStep) : console.warn(‘Hi! You should give an animation callback function to the Scroller module! :)‘); } } }, smoothScroll: function () { if (options.navigationContainer !== null) options.navigationContainer.addEventListener(‘click‘, this.doSmoothScroll); }, checkActiveStep: function () { var scrollPosition = this.scrollPosition; [].forEach.call(options.steps, function (step) { var bBox = step.getBoundingClientRect(), position = step.offsetTop, height = position + bBox.height; if (scrollPosition >= position && scrollPosition < height && currentStep !== step) { currentStep = step; step.classList.add(self.currentStepClass); if (typeof options.onStepChange === ‘function‘) options.onStepChange(step); } step.classList.remove(options.currentStepClass); }); }, destroy: function () { window.removeEventListener(‘scroll‘, throttledGetScrollPosition); window.removeEventListener(‘resize‘, throttledGetScrollPosition); options.navigationContainer.removeEventListener(‘click‘, this.doSmoothScroll); } } })(); ////////////////////// // END scroll Module ////////////////////// ////////////////////// // APP init ////////////////////// var scrollToTopBtn = document.querySelector(‘.Scroll-to-top‘), steps = document.querySelectorAll(‘.js-scroll-step‘), navigationContainer = document.querySelector(‘.Quick-navigation‘), links = navigationContainer.querySelectorAll(‘a‘), progressIndicator = document.querySelector(‘.Scroll-progress-indicator‘); ScrollManager.init({ steps: steps, scrollToTopBtn: scrollToTopBtn, navigationContainer: navigationContainer, links: links, // Customize onScroll behavior onScroll: function () { var percentage = ScrollManager.scrollPercentage(); percentage >= 90 ? scrollToTopBtn.classList.add(‘visible‘) : scrollToTopBtn.classList.remove(‘visible‘); if (percentage >= 10) { progressIndicator.innerHTML = percentage + "%"; progressIndicator.classList.add(‘visible‘); } else { progressIndicator.classList.remove(‘visible‘); } }, // Behavior when a step changes // default : highlight links // onStepChange: function (step) {}, // Customize the animation with jQuery, GSAP or velocity // default : jQuery animate() // Eg with GSAP scrollTo plugin //smoothScrollAnimation: function (target) { // TweenLite.to(window, 2, {scrollTo:{y:target}, ease:Power2.easeOut}); //} }); ////////////////////// // END APP init ////////////////////// })(); </script> </body> </html>