├── .gitignore ├── .npmignore ├── README.md ├── gulpfile.babel.js ├── index.html ├── package.json ├── page-walker.js ├── page-walker.min.js ├── page-walker.min.js.map └── src ├── jade └── index.jade └── js └── page-walker.babel.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | page-walker.min.js 2 | page-walker.min.js.map 3 | index.html 4 | gulpfile.babel.js 5 | src 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Page Walker 2 | 3 | [![NPM version](https://img.shields.io/npm/v/page-walker.svg?style=flat-square)](https://www.npmjs.com/package/page-walker) 4 | 5 | As simple as: 6 | 7 | ```javascript 8 | PageWalker.watch() 9 | ``` 10 | 11 | Then the God will know how far you have gone through the page; 12 | 13 | What if you want the God to watch your progress from the bottom? 14 | 15 | ```javascript 16 | PageWalker.bottom().watch() 17 | ``` 18 | 19 | ## License 20 | 21 | MIT. 22 | -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | import gulp from 'gulp' 2 | import babel from 'gulp-babel' 3 | import jade from 'gulp-jade' 4 | import serve from 'gulp-serve' 5 | import rename from 'gulp-rename' 6 | import uglify from 'gulp-uglify' 7 | import sourcemaps from 'gulp-sourcemaps' 8 | 9 | const paths = { 10 | js: { 11 | main: './src/js/page-walker.babel.js', 12 | js: './page-walker.js' 13 | }, 14 | jade: { 15 | src: './src/jade/*.jade' 16 | } 17 | } 18 | 19 | gulp.task('serve', serve({ 20 | port: '3003', 21 | root: '.' 22 | })) 23 | 24 | gulp.task('babel', () => { 25 | gulp.src(paths.js.main) 26 | .pipe(babel()) 27 | .pipe(rename('page-walker.js')) 28 | .pipe(gulp.dest('.')) 29 | .pipe(rename({suffix: '.min'})) 30 | .pipe(sourcemaps.init()) 31 | .pipe(uglify()) 32 | .pipe(sourcemaps.write('.')) 33 | .pipe(gulp.dest('.')) 34 | }) 35 | 36 | gulp.task('jade', () => { 37 | gulp.src(paths.jade.src) 38 | .pipe(jade({ 39 | locals: { 40 | time: Date.now() 41 | } 42 | })) 43 | .pipe(gulp.dest('.')) 44 | }) 45 | 46 | gulp.task('watch', () => { 47 | gulp.watch(paths.js.main, ['babel']) 48 | gulp.watch(paths.jade.src, ['jade']) 49 | }) 50 | 51 | gulp.task('build', ['babel', 'jade']) 52 | 53 | gulp.task('default', ['build', 'watch', 'serve']) 54 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | Page Walker

Page Walker

20 | <Just scroll and watch me dance/>

No matter how far you go, I know

You are the one who has no limits

Trough, or killed, or bounce higher

<God knows/>
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "page-walker", 3 | "version": "0.0.12", 4 | "description": "", 5 | "main": "page-walker.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "EGOIST", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "babel-core": "^5.8.24", 13 | "gulp": "^3.9.0", 14 | "gulp-babel": "^5.2.1", 15 | "gulp-jade": "^1.1.0", 16 | "gulp-rename": "^1.2.2", 17 | "gulp-serve": "^1.2.0", 18 | "gulp-sourcemaps": "^1.5.2", 19 | "gulp-uglify": "^1.4.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /page-walker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 4 | 5 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 6 | 7 | (function (W, D) { 8 | 9 | var $ = document.querySelector.bind(document); 10 | var className = 'page-walker'; 11 | var selector = '.' + className; 12 | 13 | var definition = function definition() { 14 | var PageWalker = (function () { 15 | function PageWalker() { 16 | _classCallCheck(this, PageWalker); 17 | 18 | this.bgColor = '#0A74DA'; 19 | this.position = 'top'; 20 | } 21 | 22 | _createClass(PageWalker, [{ 23 | key: 'style', 24 | value: function style() { 25 | return '\n position: fixed;\n ' + this.position + ': 0;\n background-color: ' + this.bgColor + ';\n left: 0;\n width: 0;\n height: 3px;\n z-index: 9999;\n transition: width .3s ease-in-out;\n '; 26 | } 27 | }, { 28 | key: 'watch', 29 | value: function watch() { 30 | var exitsingBar = $(selector); 31 | if (exitsingBar) { 32 | D.body.removeChild(exitsingBar); 33 | } 34 | this.getBar(); 35 | this.watchBar(); 36 | } 37 | }, { 38 | key: 'watchBar', 39 | value: function watchBar() { 40 | W.addEventListener('scroll', function () { 41 | updateProgress(); 42 | }); 43 | } 44 | }, { 45 | key: 'getBar', 46 | value: function getBar() { 47 | var bar = $(selector); 48 | if (!bar) { 49 | bar = this.initBar(); 50 | } 51 | return bar; 52 | } 53 | }, { 54 | key: 'initBar', 55 | value: function initBar() { 56 | var bar = D.createElement('div'); 57 | bar.className = className; 58 | bar.setAttribute('style', this.style()); 59 | D.body.appendChild(bar); 60 | return bar; 61 | } 62 | }, { 63 | key: 'top', 64 | value: function top() { 65 | this.position = 'top'; 66 | return this; 67 | } 68 | }, { 69 | key: 'bottom', 70 | value: function bottom() { 71 | this.position = 'bottom'; 72 | return this; 73 | } 74 | }]); 75 | 76 | return PageWalker; 77 | })(); 78 | 79 | return new PageWalker(); 80 | }; 81 | 82 | if (typeof module === 'object') { 83 | module.exports = definition(); 84 | } else if (typeof window === 'object') { 85 | window.PageWalker = definition(); 86 | } 87 | 88 | function getDocHeight() { 89 | return Math.max(D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight); 90 | } 91 | 92 | function updateProgress() { 93 | var wh = W.innerHeight; 94 | var h = height(D.body); 95 | var sHeight = h - wh; 96 | var width = Math.max(0, Math.min(1, W.scrollY / sHeight)) * 100 + '%'; 97 | $(selector).style.width = width; 98 | } 99 | 100 | function height(el) { 101 | return parseInt(getComputedStyle(el).height); 102 | } 103 | })(window, document); -------------------------------------------------------------------------------- /page-walker.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function t(t,e){for(var n=0;n { 2 | 3 | let $ = document.querySelector.bind(document) 4 | const className = 'page-walker' 5 | const selector = `.${className}` 6 | 7 | let definition = () => { 8 | class PageWalker { 9 | constructor () { 10 | this.bgColor = '#0A74DA' 11 | this.position = 'top' 12 | } 13 | style () { 14 | return ` 15 | position: fixed; 16 | ${this.position}: 0; 17 | background-color: ${this.bgColor}; 18 | left: 0; 19 | width: 0; 20 | height: 3px; 21 | z-index: 9999; 22 | transition: width .3s ease-in-out; 23 | ` 24 | } 25 | watch () { 26 | const exitsingBar = $(selector) 27 | if (exitsingBar) { 28 | D.body.removeChild(exitsingBar) 29 | } 30 | this.getBar() 31 | this.watchBar() 32 | } 33 | watchBar () { 34 | W.addEventListener('scroll', () => { 35 | updateProgress() 36 | }) 37 | } 38 | getBar () { 39 | let bar = $(selector) 40 | if (!bar) { 41 | bar = this.initBar() 42 | } 43 | return bar 44 | } 45 | initBar () { 46 | let bar = D.createElement('div') 47 | bar.className = className 48 | bar.setAttribute('style', this.style()) 49 | D.body.appendChild(bar) 50 | return bar 51 | } 52 | top () { 53 | this.position = 'top' 54 | return this 55 | } 56 | bottom () { 57 | this.position = 'bottom' 58 | return this 59 | } 60 | } 61 | 62 | return new PageWalker() 63 | } 64 | 65 | if (typeof module === 'object') { 66 | module.exports = definition() 67 | } else if (typeof window === 'object') { 68 | window.PageWalker = definition() 69 | } 70 | 71 | function getDocHeight () { 72 | return Math.max( 73 | D.body.scrollHeight, D.documentElement.scrollHeight, 74 | D.body.offsetHeight, D.documentElement.offsetHeight, 75 | D.body.clientHeight, D.documentElement.clientHeight 76 | ) 77 | } 78 | 79 | function updateProgress () { 80 | const wh = W.innerHeight 81 | const h = height(D.body) 82 | const sHeight = h - wh; 83 | const width = Math.max(0, Math.min(1, W.scrollY / sHeight)) * 100 + '%' 84 | $(selector).style.width = width 85 | } 86 | 87 | function height (el) { 88 | return parseInt(getComputedStyle(el).height) 89 | } 90 | 91 | }(window, document) 92 | --------------------------------------------------------------------------------