├── .travis.yml ├── .gitignore ├── screenshot └── shot.gif ├── .jshintrc ├── gulpfile.js ├── index.html ├── LICENSE ├── package.json ├── README.md ├── dist ├── x-return-top.min.js └── x-return-top.js └── src └── x-return-top.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.4.4" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .settings 3 | 4 | node_modules/* 5 | 6 | -------------------------------------------------------------------------------- /screenshot/shot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hustcc/return-top/HEAD/screenshot/shot.gif -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "quotmark": false, 3 | "boss": false, 4 | "eqnull": false, 5 | "expr": true, 6 | "funcscope": false, 7 | "loopfunc": false, 8 | "smarttabs": false, 9 | "node": false, 10 | "browser": false, 11 | "undef": false, 12 | "unused": false, 13 | "scripturl": true 14 | } 15 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const uglify = require('gulp-uglify'); 3 | const rename = require("gulp-rename"); 4 | const injectVersion = require('gulp-inject-version'); 5 | 6 | gulp.task('mini', () => ( 7 | gulp.src('src/x-return-top.js') 8 | .pipe(injectVersion()) 9 | .pipe(gulp.dest('dist/')) 10 | .pipe(uglify({ 11 | preserveComments: 'license' 12 | })) //uglify 13 | .pipe(rename("x-return-top.min.js")) 14 | .pipe(gulp.dest('dist/')) 15 | )); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | x-return-top demo 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hust.cc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "return-top", 3 | "officialName": "return-top", 4 | "version": "1.0.0", 5 | "summary": "Simple (2 kb) & Pure javascript achieve click image to return top of website with animation", 6 | "description": "Simple (2 kb) & Pure javascript achieve click image to return top of website with animation", 7 | "author": { 8 | "name": "hustcc", 9 | "url": "https://github.com/hustcc" 10 | }, 11 | "homepage": "http://www.atool.org/", 12 | "license": "MIT", 13 | "keywords": [ 14 | "return", 15 | "top", 16 | "return-top", 17 | "scoll-top", 18 | "go back" 19 | ], 20 | "main": "dist/x-return-top.min.js", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/hustcc/x-return-top.js" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/hustcc/x-return-top.js/issues" 27 | }, 28 | "devDependencies": { 29 | "gulp": "^3.9.0", 30 | "gulp-uglify": "^1.5.3", 31 | "jshint": "^2.9.2", 32 | "gulp-rename": "^1.2.2", 33 | "gulp-inject-version": "^1.0.1" 34 | }, 35 | "scripts": { 36 | "lint": "jshint src/x-return-top.js", 37 | "test": "npm run lint", 38 | "build": "gulp mini && npm run test" 39 | }, 40 | "dependencies": { 41 | } 42 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # x-return-top 3 | 4 | 5 | > 纯javascript代码实现的“返回顶部”功能,代码非常简单,集成起来更简单,代码大小只有2.2kb,并且提供CDN,完全不会拖慢你的网站速度。 6 | 7 | 在制作网页中,经常会发现网页非常长,为了用户的方便,都会设置返回顶部的按钮,用户一键返回网页顶部; 8 | 如果你的网站中使用jquery,那么有很多的插件可以完成这个工作,可以在git中搜索很多。 9 | 10 | 然而,如果你的网页中没有使用jquery,那么如果要使用这些插件,就必须为了这一个很小的功能,加上jquery,对于网页的加载速度非常不划算。 11 | 12 | 13 | ## 使用 ## 14 | 15 | 使用非常简单,如下所示,放到Body之间即可,切勿放到head中。 16 | 17 | 18 | 19 | 20 | ## 配置项 21 | 22 | - `left`: 位置定位左侧, 默认: `'80%'` 23 | - `bottom`: 位置定位右侧, 默认: `15%` 24 | - `text`: 显示的文本内容, 默认: `Back Top` 25 | 26 | 例如: 27 | 28 | 29 | 30 | 31 | ## 说明 ## 32 | 33 | - git上大部分的“返回顶部”项目都是基于jquery,使用前必须应用jquery 34 | - git上部分纯javascript实现的“返回顶部”,无动画,不美观 35 | - 本项目使用纯javascript,实现动画,美观且不影响网页加载速度,不依赖任何js框架 36 | - 压缩之后2.2kb 37 | - 集成非常简单 38 | - 使用部分css3动画,所以兼容性你懂的(但是不会影响使用,后续会改为js动画) 39 | - css使用js动态加载,集成更方便,且不影响网页加载速度 40 | - 图片使用base64加载,不会增加http请求数 41 | 42 | 43 | ## Demo ## 44 | 45 | - Live Demo 1: [https://aibq.cn](https://aibq.cn) 46 | - Live Demo 2: [http://www.atool.org](http://www.atool.org) 47 | - 项目代码中的index.html 48 | ![](https://raw.githubusercontent.com/hustcc/x-return-top.js/master/screenshot/shot.gif) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /dist/x-return-top.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.0 5 | * GitHub: https://github.com/hustcc/x-return-top.js 6 | **/ 7 | !function(){function t(){n(),x(),b();var t=window.onscroll;window.onscroll=function(){"function"==typeof t&&t.call(this),p()},g.onclick=a,h.onmouseover=i,h.onmouseout=A}function o(t){return document.getElementsByTagName(t)}function e(t,o,e){return t.getAttribute(o)||e}function n(){var t=o("script"),n=t[t.length-1];v={l:e(n,"left","80%"),b:e(n,"bottom","15%"),t:e(n,"text","Back Top")}}function A(){h.style.width="36px"}function i(){h.style.width="100px"}function r(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0}function u(t){document.body&&document.body.scrollTop&&(document.body.scrollTop=t),document.documentElement&&document.documentElement.scrollTop&&(document.documentElement.scrollTop=t)}function d(){h.style.bottom="-60px"}function l(){h.style.bottom=v.b}function c(){u(r()/1.15),r()<1&&(clearInterval(T),T=null)}function a(){A(),T=setInterval(c,10)}function p(){T||(r()>5?l():d())}function s(t){return document.createElement(t)}function m(t){return document.createTextNode(t)}function f(t,o){t.appendChild(o)}function x(){g=s("div"),g.id="xReturnTop",h=s("div"),h.style.overflow="hidden";var t=s("a");t.href="javascript:void(0)";var e=s("span");f(e,m(v.t)),f(h,t),f(h,e),f(g,h),f(o("body")[0],g)}function b(){var t=document.createElement("div"),e="#xReturnTop{font-size:12px;position:fixed;}#xReturnTop div,#xReturnTop div a{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;width:36px;height:36px;display:block;}#xReturnTop div{transition:0.3s;position:fixed;left:"+v.l+';bottom:-60px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkAQMAAADbzgrbAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAABdFJOU1wiO8W5AAAADElEQVQI12NgGJ4AAADYAAHoUyD/AAAAAElFTkSuQmCC") repeat;cursor:pointer;}#xReturnTop div a{float:left;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAARAQMAAAA4xGTiAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAGUExURQAAAP///6XZn90AAAABdFJOUwBA5thmAAAAJ0lEQVQI12P4/48BiCCAkYGBuYGB/QAD/wMG+Q8M9j8Y6v+AuKgIAH0DDqBH4KCCAAAAAElFTkSuQmCC") no-repeat 11px 10px;}#xReturnTop div a:hover{background-color:#6e6e6e;}#xReturnTop div span{float:left;line-height:36px;color:#e6e6e6;margin-left:6px;}';t.innerHTML="x",f(o("head")[0],t.lastChild)}var v,T,g,h;t()}(); -------------------------------------------------------------------------------- /dist/x-return-top.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.0 5 | * GitHub: https://github.com/hustcc/x-return-top.js 6 | **/ 7 | ! function() { 8 | var opt,__returnTopInterval,xEle,xBox; 9 | //x-return-top.js执行方法 10 | function xReturnTop() { 11 | __getOption(); 12 | __addHtml(); 13 | __addCss(); 14 | //防止屏蔽已有的事件 15 | var oldOnscroll = window.onscroll; 16 | window.onscroll = function () { 17 | if(typeof oldOnscroll == 'function'){ 18 | oldOnscroll.call(this); 19 | } 20 | __onWindowScroll(); 21 | }; //卷动事件 22 | xEle.onclick = __animateReturnTop; //点击 23 | xBox.onmouseover = __onBoxMouseOver; //鼠标 24 | xBox.onmouseout = __onBoxMouseOut; 25 | } 26 | 27 | function __getElesByTag(name) { 28 | return document.getElementsByTagName(name); 29 | } 30 | 31 | function __getAttr(node, attrName, defaultValue) { 32 | return node.getAttribute(attrName) || defaultValue; 33 | } 34 | 35 | function __getOption() { 36 | var scripts = __getElesByTag('script'), script = scripts[scripts.length - 1]; 37 | opt = { 38 | l: __getAttr(script, 'left', '80%'), 39 | b: __getAttr(script, 'bottom', '15%'), 40 | t: __getAttr(script, 'text', 'Back Top') 41 | }; 42 | } 43 | 44 | function __onBoxMouseOut() { 45 | xBox.style.width = '36px'; 46 | } 47 | 48 | function __onBoxMouseOver() { 49 | xBox.style.width = '100px'; 50 | } 51 | 52 | function __getScrollTopOffset() { 53 | return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; 54 | } 55 | 56 | function __setScrollTopOffset(value) { 57 | if (document.body && document.body.scrollTop) { 58 | document.body.scrollTop = value; 59 | } 60 | if (document.documentElement && document.documentElement.scrollTop) { 61 | document.documentElement.scrollTop = value; 62 | } 63 | } 64 | 65 | function __animateHideXReturnTop() { 66 | xBox.style.bottom = '-60px'; 67 | } 68 | 69 | //显示按钮动画 70 | function __animateShowXReturnTop() { 71 | xBox.style.bottom = opt.b; 72 | } 73 | 74 | function __scrollMove() { 75 | __setScrollTopOffset(__getScrollTopOffset() / 1.15); 76 | //滚动到最上面的时候,清除定时器 77 | if (__getScrollTopOffset() < 1) { 78 | clearInterval(__returnTopInterval); 79 | __returnTopInterval = null; 80 | } 81 | } 82 | function __animateReturnTop() { 83 | __onBoxMouseOut(); 84 | __returnTopInterval = setInterval(__scrollMove, 10); //每10毫秒只是一次方法 85 | } 86 | 87 | function __onWindowScroll() { 88 | if (!__returnTopInterval) __getScrollTopOffset() > 5 ? __animateShowXReturnTop() : __animateHideXReturnTop(); 89 | } 90 | 91 | function __createNonde(tag) { 92 | return document.createElement(tag); 93 | } 94 | 95 | function __createText(t) { 96 | return document.createTextNode(t); 97 | } 98 | function __append(p, c) { 99 | p.appendChild(c); 100 | } 101 | 102 | function __addHtml() { 103 | xEle = __createNonde('div'); 104 | xEle.id = 'xReturnTop'; 105 | 106 | xBox = __createNonde('div'); 107 | xBox.style.overflow = 'hidden'; 108 | 109 | var xA = __createNonde('a'); 110 | xA.href = 'javascript:void(0)'; 111 | 112 | var xSpan = __createNonde('span'); 113 | __append(xSpan, __createText(opt.t)); 114 | 115 | __append(xBox, xA); 116 | __append(xBox, xSpan); 117 | __append(xEle, xBox); 118 | __append(__getElesByTag('body')[0], xEle); 119 | } 120 | 121 | function __addCss() { 122 | var x = document.createElement('div'), 123 | cssStr = '#xReturnTop{font-size:12px;position:fixed;}#xReturnTop div,#xReturnTop div a{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;width:36px;height:36px;display:block;}#xReturnTop div{transition:0.3s;position:fixed;left:'+opt.l+';bottom:-60px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkAQMAAADbzgrbAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAABdFJOU1wiO8W5AAAADElEQVQI12NgGJ4AAADYAAHoUyD/AAAAAElFTkSuQmCC") repeat;cursor:pointer;}#xReturnTop div a{float:left;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAARAQMAAAA4xGTiAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAGUExURQAAAP///6XZn90AAAABdFJOUwBA5thmAAAAJ0lEQVQI12P4/48BiCCAkYGBuYGB/QAD/wMG+Q8M9j8Y6v+AuKgIAH0DDqBH4KCCAAAAAElFTkSuQmCC") no-repeat 11px 10px;}#xReturnTop div a:hover{background-color:#6e6e6e;}#xReturnTop div span{float:left;line-height:36px;color:#e6e6e6;margin-left:6px;}'; 124 | x.innerHTML = 'x'; 125 | __append(__getElesByTag('head')[0], x.lastChild); 126 | } 127 | xReturnTop(); 128 | }(); -------------------------------------------------------------------------------- /src/x-return-top.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: %%GULP_INJECT_VERSION%% 5 | * GitHub: https://github.com/hustcc/x-return-top.js 6 | **/ 7 | ! function() { 8 | var opt,__returnTopInterval,xEle,xBox; 9 | //x-return-top.js执行方法 10 | function xReturnTop() { 11 | __getOption(); 12 | __addHtml(); 13 | __addCss(); 14 | //防止屏蔽已有的事件 15 | var oldOnscroll = window.onscroll; 16 | window.onscroll = function () { 17 | if(typeof oldOnscroll == 'function'){ 18 | oldOnscroll.call(this); 19 | } 20 | __onWindowScroll(); 21 | }; //卷动事件 22 | xEle.onclick = __animateReturnTop; //点击 23 | xBox.onmouseover = __onBoxMouseOver; //鼠标 24 | xBox.onmouseout = __onBoxMouseOut; 25 | } 26 | 27 | function __getElesByTag(name) { 28 | return document.getElementsByTagName(name); 29 | } 30 | 31 | function __getAttr(node, attrName, defaultValue) { 32 | return node.getAttribute(attrName) || defaultValue; 33 | } 34 | 35 | function __getOption() { 36 | var scripts = __getElesByTag('script'), script = scripts[scripts.length - 1]; 37 | opt = { 38 | l: __getAttr(script, 'left', '80%'), 39 | b: __getAttr(script, 'bottom', '15%'), 40 | t: __getAttr(script, 'text', 'Back Top') 41 | }; 42 | } 43 | 44 | function __onBoxMouseOut() { 45 | xBox.style.width = '36px'; 46 | } 47 | 48 | function __onBoxMouseOver() { 49 | xBox.style.width = '100px'; 50 | } 51 | 52 | function __getScrollTopOffset() { 53 | return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; 54 | } 55 | 56 | function __setScrollTopOffset(value) { 57 | if (document.body && document.body.scrollTop) { 58 | document.body.scrollTop = value; 59 | } 60 | if (document.documentElement && document.documentElement.scrollTop) { 61 | document.documentElement.scrollTop = value; 62 | } 63 | } 64 | 65 | function __animateHideXReturnTop() { 66 | xBox.style.bottom = '-60px'; 67 | } 68 | 69 | //显示按钮动画 70 | function __animateShowXReturnTop() { 71 | xBox.style.bottom = opt.b; 72 | } 73 | 74 | function __scrollMove() { 75 | __setScrollTopOffset(__getScrollTopOffset() / 1.15); 76 | //滚动到最上面的时候,清除定时器 77 | if (__getScrollTopOffset() < 1) { 78 | clearInterval(__returnTopInterval); 79 | __returnTopInterval = null; 80 | } 81 | } 82 | function __animateReturnTop() { 83 | __onBoxMouseOut(); 84 | __returnTopInterval = setInterval(__scrollMove, 10); //每10毫秒只是一次方法 85 | } 86 | 87 | function __onWindowScroll() { 88 | if (!__returnTopInterval) __getScrollTopOffset() > 5 ? __animateShowXReturnTop() : __animateHideXReturnTop(); 89 | } 90 | 91 | function __createNonde(tag) { 92 | return document.createElement(tag); 93 | } 94 | 95 | function __createText(t) { 96 | return document.createTextNode(t); 97 | } 98 | function __append(p, c) { 99 | p.appendChild(c); 100 | } 101 | 102 | function __addHtml() { 103 | xEle = __createNonde('div'); 104 | xEle.id = 'xReturnTop'; 105 | 106 | xBox = __createNonde('div'); 107 | xBox.style.overflow = 'hidden'; 108 | 109 | var xA = __createNonde('a'); 110 | xA.href = 'javascript:void(0)'; 111 | 112 | var xSpan = __createNonde('span'); 113 | __append(xSpan, __createText(opt.t)); 114 | 115 | __append(xBox, xA); 116 | __append(xBox, xSpan); 117 | __append(xEle, xBox); 118 | __append(__getElesByTag('body')[0], xEle); 119 | } 120 | 121 | function __addCss() { 122 | var x = document.createElement('div'), 123 | cssStr = '#xReturnTop{font-size:12px;position:fixed;}#xReturnTop div,#xReturnTop div a{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;width:36px;height:36px;display:block;}#xReturnTop div{transition:0.3s;position:fixed;left:'+opt.l+';bottom:-60px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkAQMAAADbzgrbAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAABdFJOU1wiO8W5AAAADElEQVQI12NgGJ4AAADYAAHoUyD/AAAAAElFTkSuQmCC") repeat;cursor:pointer;}#xReturnTop div a{float:left;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAARAQMAAAA4xGTiAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAGUExURQAAAP///6XZn90AAAABdFJOUwBA5thmAAAAJ0lEQVQI12P4/48BiCCAkYGBuYGB/QAD/wMG+Q8M9j8Y6v+AuKgIAH0DDqBH4KCCAAAAAElFTkSuQmCC") no-repeat 11px 10px;}#xReturnTop div a:hover{background-color:#6e6e6e;}#xReturnTop div span{float:left;line-height:36px;color:#e6e6e6;margin-left:6px;}'; 124 | x.innerHTML = 'x'; 125 | __append(__getElesByTag('head')[0], x.lastChild); 126 | } 127 | xReturnTop(); 128 | }(); --------------------------------------------------------------------------------