Jquery回到頂部功能

龍恩0707發表於2013-08-28

    問題描述: 

       在網頁中,我們經常會由於網頁內容過長,而需要在瀏覽網頁時有一個快速回到網頁頂部的功能,在瀏覽網頁內容離頂部有一段距離時,出現快速回到網頁頂部的工具,從而能使我們的網頁更人性化。

   問題的產生:

       前幾天由於在公司做了個小專案中正好有一個這樣的功能,當時也是以前同事用kissy框架寫的元件,感覺蠻好用的,所以想能不能用Jquery把他們封裝起來 這樣以後如果離開了阿里系,那麼就不可能用kissy框架 肯定大部分是用jquery框架了 ,所以.......  但是在這個程式碼之前在谷歌遊覽器下有個小小的bug。我想知道滾動top時候 用document.documentElement.scrollTop; 既然計算不到準確的值,經過仔細分析,發現Chrome對document.documentElement.scrollTop的識別會出現誤差。不過加上document.body.scrollTop後,則顯示正常。由於document.documentElement.scrollTop和document.body.scrollTop在標準模式或者是奇怪模式下都只有一個會返回有效的值,所以都加上也不會有問題(看來上面的問題是Chrome可能把文件當作非標準文件來解析了)。

程式碼如下 由於有詳細的註釋 所以可以直接看註釋。

    /**
 * Setting:
 * !!! css中需設定{width:**;bottom:**;},否則後果自負,哈哈
 *
 * 預設引數:
        topLink:'.top', //toplink
        markupType: 0, //預設為0:居中,1:居左,2:居右
        contentWidth: 1000, //佈局寬度
        paddingWidth: 5, //僅當居右(左)時生效,表示距佈局右(左)側的間隔;
        leftOffset: 0, //僅當居中時生效,divbar左側 需要超出佈局的寬度
        //left和right 僅在markupType為-1 和 -2時有用。表示距視窗最左和最右的間隔
        left:0,
        right:0,
        //!!!top和bottom 必須設定其一 預設為top:0,頂對齊。
        YAlign: {
            top:0
        },
        zIndex:99999,//z-index屬性
        display: 0//預設首屏不顯示,為1則首屏顯示。


        //水平居中,頂部(間隔用YAlign: {top:0}設定,預設為0)
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: 0
        });
        //水平居中,底部(間隔用YAlign: {bottom:'10px'}設定)
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: 0,
            YAlign: {
                bottom:0
            }
        });
        //水平居左靠近主體左側,頂部(間隔用YAlign: {top:0}設定)
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: 1
        });
        //水平居左靠近主體左側,底部(間隔用YAlign: {bottom:'10px'}設定)
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: 1,
            YAlign: {
                bottom:0
            }
        });
        //水平居左,頂部(間隔用YAlign: {top:0}設定),左側距離用style
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: -1,
            left:'5px'
        });
        //水平居左,底部(間隔用YAlign: {bottom:'10px'}設定),左側距離用left
        new ActiveTool('#divbar',{
            topLink:'.top',//class or id
            markupType: -1,
            left:'5px',
            YAlign: {
                bottom:0
            }
        });

    ****水平居右與水平居左類似****

 * @change log:
 * 2013-8-20 tugenhua@126.com
 *
 */
var ActiveTool = (function(win,undefined){
    var doc = document,
        docBody = doc.body,
        isIE = navigator.userAgent.match(/MSIE/)!= null,
        isIE6 = navigator.userAgent.match(/MSIE 6.0/)!= null,
        docelem = doc.documentElement || docBody;

    function ActiveTool(container,config){
        var self = this;
        if(!(self instanceof ActiveTool)){
            return new ActiveTool(container,config);
        }
        config = $.extend(ActiveTool.Config,config);

        self.config = config || {};
        // 匹配傳參container
        if($.isPlainObject(container)){
            self.container = container;
        }else if(/^\./.test(container)){
            self.container = $(container);
        }else if(/^#/.test(container)){
            self.container = $(container);
        }else if($('.'+container)){
            self.container = $('.'+container);
        }else{
            throw new Error('點選元素傳遞引數不符合!');
        }
        self._init();
    }
    
    // 預設配置

    ActiveTool.Config = {
        topLink: '.top',
        markupType: 0,
        contentWidth: 1000,
        paddingWidth: 5,
        leftOffset: 0,
        left:0,
        right:0,
        YAlign: {
            top:0
        },
        zIndex:99999,
        display: 0    
    };
    ActiveTool.prototype = {
        _init: function(){
            var self = this,
                cfg = self.config,
                EVT_SCROLL = 'scroll',
                EVT_RESIZE = 'resize',
                divBar;
            // init divBar node
            divBar = self.container;
            
            // init position
            self._calcPos();

            // 首屏是否顯示
            if(cfg.display === 0){
                $(divBar).css({"opacity":0})
                $(divBar).css('zIndex',-1);
            }else{
                $(divBar).css({"opacity":1});
                $(divBar).css('zIndex',cfg.zIndex);

            }

            var topLink = $(cfg.topLink,divBar);
            if (topLink){
                // hide focus for ie
                if (isIE) {
                    topLink.hideFocus = true;
                }
                $(topLink).bind('click',function(e){
                    e.preventDefault();
                    $(topLink).unbind('click');
                    docelem.scrollTop = 0;
                });
            }
            
            // do decoration on scrolling
            
            $(win).bind(EVT_SCROLL,function(e){
                self._decorate(true);
            });

            $(win).bind(EVT_RESIZE,function(e){
                self._decorate(false);
            });
        },
        //計算各瀏覽下的定位座標
        _calcPos: function(){
            var self = this,
                cfg = self.config,
                PX = 'px',
                TOP = 'top',
                BOTTOM = 'bottom',
                LEFT = 'left',
                RIGHT = 'right',
                contentWidth = cfg.contentWidth,
                paddingWidth = cfg.paddingWidth,
                leftOffset = cfg.leftOffset,
                divBar = self.container,
                top = cfg.YAlign.top,
                bottomPadding = parseInt(cfg.YAlign.bottom,10),
                topPadding = parseInt(top,10),
                selfHeight = parseInt($(divBar).css('height'),10),//divbar自身高度
                selfWidth = parseInt($(divBar).css('width'),10),//divbar自身寬度
                xPos,
                checkMarkup = function(viewWidth){
                    switch (true){

                        case cfg.markupType === 0:
                            xPos = Math.floor((viewWidth - contentWidth) / 2) - leftOffset;
                            break;

                        case cfg.markupType === 2:
                            xPos = Math.floor((viewWidth - contentWidth) / 2) + contentWidth + paddingWidth;
                            break;

                        case cfg.markupType === -2:
                            xPos = parseInt(cfg.right,10);
                            $(divBar).css(RIGHT, xPos + PX);
                            break;

                        case cfg.markupType === 1:
                            xPos = Math.floor((viewWidth - contentWidth) / 2) - paddingWidth - selfWidth;
                            break;

                        case cfg.markupType === -1:
                            xPos = parseInt(cfg.left,10);
                            break;

                        default:
                            xPos = Math.floor((viewWidth - contentWidth) / 2) - leftOffset;
                    }
                },
                cal;
            if (true === isIE6) {
                // for IE6
                cal = function(scrolling){
                    var viewHeight = $(win).height(),
                        scrollTop = docelem.scrollTop,
                        yPos;

                    if (top !== undefined){
                        yPos = topPadding + scrollTop;
                    } else {
                        yPos = viewHeight - bottomPadding - selfHeight + scrollTop;
                    }

                    // on scrolling
                    if (scrolling) {
                        DOM.css(divBar, TOP, yPos + PX);
                        return;
                    }

                    var viewWidth = $(win).width();
                    checkMarkup(viewWidth);
                    $(divBar).css({'position':'absolute'});
                    $(divBar).css(TOP, yPos + PX);
                    if (cfg.markupType === -2){return;}
                    $(divBar).css(LEFT, xPos + PX);
                };
            } else if (isIE) {
                // for IE7+ (ie9有待驗證)
                cal = function () {
                    $(divBar).css({'position':'fixed'});
                    top !== undefined ? $(divBar).css(TOP, topPadding + PX) : $(divBar).css(BOTTOM, bottomPadding + PX);
                    var viewWidth = $(win).width();
                    checkMarkup(viewWidth);
                    if (cfg.markupType === -2){return;}
                    $(divBar).css(LEFT, xPos + PX);
                };
            } else {
                // for non-IE
                cal = function () {
                    
                    $(divBar).css({'position':'fixed'});
                    top !== undefined ? $(divBar).css(TOP, topPadding + PX) : $(divBar).css(BOTTOM, bottomPadding + PX);
                    var viewWidth = document.body.clientWidth;
                    checkMarkup(viewWidth);
                    if (cfg.markupType === -2){return;}
                    $(divBar).css(LEFT, xPos + PX);
                };
            }
            self._calcPos = cal;
            return cal();
        },
        /* win 註冊 scroll resize 事件
         * @param flag -> true 指滾動 flag -> false 指縮放
         */
        _decorate: function(flag){
            var self = this,
                cfg = self.config,
                divBar = self.container,
                DELAY = 100,
                scrollTimer,
                resizeTimer;
            if(flag){
                var scrollTop = document.documentElement.scrollTop + document.body.scrollTop;
                if(0 === scrollTop && cfg.display === 0){
                    $(divBar).css({'opacity':0});
                    $(divBar).css('zIndex', -1);
                }else {
                    $(divBar).css({'opacity':1});
                    $(divBar).css('zIndex', cfg.zIndex);
                    scrollTimer && clearTimeout(scrollTimer);
                    scrollTimer = setTimeout(function(){
                        self._calcPos();
                    },DELAY);
                }
            }else{
                resizeTimer && clearTimeout(resizeTimer);
                resizeTimer = setTimeout(function(){
                    self._calcPos();
                },DELAY);
            }
        }
    };
    return ActiveTool;

})(window);

 

 

 

 

相關文章