問題描述:
在網頁中,我們經常會由於網頁內容過長,而需要在瀏覽網頁時有一個快速回到網頁頂部的功能,在瀏覽網頁內容離頂部有一段距離時,出現快速回到網頁頂部的工具,從而能使我們的網頁更人性化。
問題的產生:
前幾天由於在公司做了個小專案中正好有一個這樣的功能,當時也是以前同事用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);