Lite Add button for Smooth Scroll to the top / bottom

为页面添加按钮,平滑的滚动到顶部/底部

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name    Lite Add button for Smooth Scroll to the top / bottom
// @author  burningall
// @description 为页面添加按钮,平滑的滚动到顶部/底部
// @version     2015.8.17
// @include     *
// @grant       GM_addStyle
// @run-at      document-start
// @compatible  chrome  完美支持
// @compatible  firefox  完美支持
// @license     The MIT License (MIT); http://opensource.org/licenses/MIT
// @supportURL      http://www.burningall.com
// @contributionURL [email protected]|alipay.com
// @namespace https://greasyfork.org/zh-CN/users/3400-axetroy
// ==/UserScript==
// 
// 
// 
//=======快捷键======
//alt+1>>>>>>回到顶部
//alt+2>>>>>>去到底部
//================公共函数区============
(function(window,document){

function addEvent(obj, type, fn){
    return obj.addEventListener ?
            obj.addEventListener(type, function(e){
                var ev = window.event ? window.event : (e ? e : null);
                ev.target = ev.target || ev.srcElement;
                if( fn.call(obj,ev)===false ){//回掉函数为false,则阻止默认时间
                    e.cancelBubble = true;//阻止冒泡
                    e.preventDefault();//chrome,firefox下阻止默认事件
                }
            }, false)
             :
            obj.attachEvent('on' + type, function(e){
                //fn.call(obj,e);//解决IE8下,this是window的问题
                var ev = window.event ? window.event : (e ? e : null);
                ev.target = ev.target || ev.srcElement;
                if(fn.call(obj,ev)===false ){
                    e.cancelBubble = true;//阻止冒泡
                    return false;//阻止默认事件,针对IE8
                }
            });
}

function getSize(obj) {
    return document.documentElement[obj] !== 0 ? document.documentElement[obj] : document.body[obj];
}

function hasScroll() {
    return getSize('scrollHeight') > getSize('clientHeight') ? true : false;
}

function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
}

function $(id) {
    return document.getElementById(id);
}
function animate(obj,json,cfgjson){
        clearInterval(obj.animate);
        obj.animate = setInterval(function() {
            var bStop = true;//判断运动是否停止
            for(var attr in json){//attr代表属性,'width','height'.而json[attr]代表数值
                // 1. 取得当前的值(可以是width,height,opacity等的值)
                var objAttr = 0 ;
                if(attr == 'opacity'){ //当前值
                    objAttr = Math.round(parseFloat( getStyle(obj,attr) ) * 100);
                }else if( attr=="scrollTop" ){
                    objAttr = parseInt( getSize("scrollTop") );
                }
                else{
                    objAttr = parseInt( getStyle(obj,attr) );
                }
                // 2.计算运动速度
                var jsonattr = parseFloat( json[attr] );//目标值
                var speedConfig = (cfgjson && typeof ( cfgjson.speed ) != 'undefined') ? cfgjson.speed : 10;
                var iSpeed = (jsonattr - objAttr) / speedConfig;    //(目标数值-当前数值)/10
                iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);   //如果速度>0,则速度向上取整,如果小于0,则保留小数
                // 3. 检测所有运动是否到达目标
                //objAttr,当前点,json[attr]为目标点
                if ( (iSpeed>0 && objAttr <= jsonattr) || (iSpeed<0 && objAttr >= jsonattr) ) {//如果有其中一项没有达到目标
                    bStop = false;
                }
                if (attr == "opacity") {
                    obj.style.filter = 'alpha(opacity:' + (objAttr + iSpeed) + ')';
                    obj.style.opacity = (objAttr + iSpeed) / 100;
                }else if(attr == "scrollTop"){
                    document.documentElement.scrollTop=document.body.scrollTop = objAttr+iSpeed;
                }
                else {
                    obj.style[attr] = objAttr + iSpeed + 'px';  //赋值开始运动
                }
                if (bStop) { // 表示所有运动都到达目标值
                    clearInterval(obj.animate);
                    if( cfgjson && typeof cfgjson.endFn != 'undefined' ){
                        cfgjson.endFn.call(obj);
                    }
                }
            }//for
        },20);
}
//================样式区============
var cssText = '#scrollMars-troy{position:fixed;right:30px;z-index:9999999}#scrollMars-troy #mars-point{width:100px;height:100px;position:absolute;top:0;left:-40px}#scrollMars-troy div div.sroll-btn-troy{width:50px;height:50px;text-align:center;background:#303030;color:#fff;display:block;opacity:0.8;filter:alpha(opacity=80);cursor:pointer;border-radius:50%;box-shadow:2px 2px 40px 2px #303030;line-height:50px;font-size:35px;font-style:inherit;font-weight:bold;font-family:"宋体"}#scrollMars-troy div div.sroll-btn-troy:hover{background:#FF0000}';
GM_addStyle(cssText);
//================主要代码区============
function scroll(dir) { //obj随意,dir>0往上滚,dir<0往下滚
    var position,speed,scrollTop,scrollHeight,clientHeight;
    clearInterval(document.timerScroll);
    scrollHeight = getSize('scrollHeight');
    clientHeight = getSize('clientHeight');
    document.timerScroll = setInterval(function() {
        scrollTop = getSize('scrollTop');   
        if (dir > 0) { //往上滚动
            speed = ( scrollTop/10 ) + 1;
            position = scrollTop - speed;
            if (position <= 0) { //如果滚到顶部
                document.body.scrollTop = document.documentElement.scrollTop = 0;
                clearInterval(document.timerScroll);
            }
        } else { //往下滚动
            speed = ( (scrollHeight-scrollTop-clientHeight) / 10 ) + 1;
            position = scrollTop + speed;
            if (position + clientHeight >= scrollHeight) { //如果滚到底部
                document.body.scrollTop = document.documentElement.scrollTop = scrollHeight;
                clearInterval(document.timerScroll);
            }
        }
        document.body.scrollTop = document.documentElement.scrollTop = position;
    }, 20);
}

function marsMove(dir){
    var mars = $('scrollMars-troy');
    var point = $('mars-point');
    if(dir=="moveIn"){//移入
        clearTimeout(mars.timerHover); 
        animate(mars,{"right":"30","opacity":"100"});
        animate(point,{"left":"0"});
    }else if(dir=="moveOut"){//移出
        clearTimeout(mars.timerHover);
        mars.timerHover = setTimeout(function(){
            animate(mars,{"right":"-30","opacity":"30"});
            animate(point,{"left":"-40"});
        },3000);
    }
}

function init() {
    var scrollBtn = $("scrollMars-troy");
    if( scrollBtn ){
        scrollBtn.style.top = (getSize('clientHeight') / 3) + 'px';
    }
    if (hasScroll() === true && !scrollBtn) { //如果有滚动条,并且没有按钮
        var mars = document.createElement('div'),goTop,goBtm,point;
        mars.id = "scrollMars-troy";
        window.top.document.documentElement.appendChild(mars);
        mars.innerHTML = 
            '<div id=\'mars-point\'></div>'+
            '<div>'+
            '    <div id=\'goTop-troy\' title=\'返回顶部\' class=\'sroll-btn-troy\'></div>'+
            '    <div id=\'goBtm-troy\' title=\'去到底部\' class=\'sroll-btn-troy\'></div>'+
            '</div>';
        goTop = $("goTop-troy");
        goBtm = $("goBtm-troy");
        goTop.innerHTML = "↑";
        goBtm.innerHTML = "↓";
        $('scrollMars-troy').style.top = (getSize('clientHeight') / 3) + 'px';
        addEvent(goTop, "click", function() {
            scroll(1);
            return false;
        });
        addEvent(goBtm, "click", function() {
            scroll(-1);
            return false;
        });
        addEvent(mars,'mouseover',function(){
            marsMove("moveIn");
            return false;
        });
        addEvent(mars,'mouseout',function(){
            marsMove("moveOut");
            return false;
        });
        addEvent(mars,'mousedown',function(){
            return false;
        });
        marsMove("moveOut");
    }
}
//================执行区============
addEvent(window,"mousewheel",function(){
    clearInterval(document.timerScroll);
});
addEvent(window,"DOMMouseScroll",function(){
    clearInterval(document.timerScroll);
});
addEvent(window.top, "resize", function() { //页面大小改变,初始化按钮
    init();
});

addEvent(document, 'DOMContentLoaded', function() {
    init();
});
//================快捷键区============
addEvent(window, 'keydown', function(e) {
    if (e.altKey && e.keyCode == 49) { //alt+1,向上滚动
        scroll(1);
    } else if (e.altKey && e.keyCode == 50) { //alt+2,向下滚动
        scroll(-1);
    } else if (e.ctrlKey && e.altKey) { //ctrl+alt,调出按钮
        marsMove("moveIn");
    } 
});//监听keydown,快捷键

})(window,document);