1、 前言
前段时间,需要做一个类似腾讯微博的锚点重置组件功能:当滚动页面时,页面右下角出现一个跳转到页面顶部的按钮,并一直浮动。如下图所示:
同时,在滚动到页面底端时,要做到如下效果:
当滚动条处于页面最顶端时,默认隐藏该组件。
2、 实现
首先是页面实现,主要代码如下:
#goTop a{background:url(http://mat1.gtimg.com/news/newlist/goTop.png) no-repeat;width:35px;height:35px;line-height:99em;overflow:hidden;position:fixed;_position:absolute;bottom:60px;margin-left:959px;} <div id="goTop" style="display: block;" mce_style="display: block;"><a href="#" mce_href="#" style="bottom: 240px;">返回顶部</a></div>
IE7,IE8,firefox和chrome下很好实现,只需要设置该组件的style样式为position:fixed就可以了,然后用js控制一下当滚动到页面底部的该组件的高度。
但是最让人头疼的是IE6,该浏览器下position的fixed不好使……这万恶的IE6。没办法,只好使用js模拟:当滚动条滚动时,调用js设置该组件的位置。
1、注册滚动条的onscroll事件。window.οnscrοll=collectScroll;
2、为了防止每次滚动条滚动时都去用js设置该组件的高度从而导致页面交互不好,采用了延迟设置该组件的高度的技术。在滚动条滚动从而触发滚动事件A时,调用response=setTimeout(func,200)函数延迟200ms(人眼的感觉)后再去设置组件高度。如果下次滚动条滚动再次触发滚动事件B时,如果距离上次滚动事件A的时间间隔小于200ms,那么就清除上次设置的时间句柄clearTimeout(response)。
3、我们还要小心用户触发resize事件,当浏览器大小改变时,需要重新设置该组件的高度。这需要注册window.οnresize=resizeEvent;
4、此外,我们还需要注意,在IE7下面,点击该组件时,并不会跳到该页面的顶端,总是有段距离,如下图所示。这需要我们继续打补丁window.scrollTo(0,0);
主要代码如下:
//浏览器类型 var Browser=(function() { var ua = navigator.userAgent; var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; return { isIE: !!window.attachEvent && !isOpera, isOpera: isOpera, isSafari: ua.indexOf('AppleWebKit/') > -1, isFirefox: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, MobileSafari: /Apple.*Mobile.*Safari/.test(ua), isChrome: !!window.chrome }; })(); Browser.isIE6=Browser.isIE&&!window.XMLHttpRequest; Browser.isIE7=Browser.isIE&&!!window.XMLHttpRequest; function addEvent(e,evt,fn,isID) { if(isID==true) { e=$(e); } if(!empty(e.attachEvent) && (typeof(e.attachEvent)=="function" || typeof(e.attachEvent)=="object")) { e.attachEvent("on"+evt,fn); } else if(!empty(e.addEventListener) && (typeof(e.addEventListener)=="function" || typeof(e.addEventListener)=="object")) { e.addEventListener(evt,fn,false); } } function getScrollPosition() { if(Browser.isIE6) return {left:document.body.scrollLeft,top:document.body.scrollTop||document.documentElement.scrollTop}; if(document.documentElement) { return {left:document.documentElement.scrollLeft,top:document.body.scrollTop||document.documentElement.scrollTop}; } else return {left:document.body.scrollLeft,top:document.body.scrollTop}; } var client_h = document.documentElement.clientHeight || document.body.clientHeight || 0; var max_height=$('cb_all').offsetTop+$('cb_all').offsetHeight; var gotoTop=$('goTop'); if(null!==gotoTop) { gotoTop.style.display="none"; if(Browser.isIE7) { addEvent(gotoTop,"click",function(){window.scrollTo(0,0);return false;},false); } } var response = null; function collectScroll() { if(null==gotoTop || gotoTop.childElementCount==0) return; if(null!==response) { clearTimeout(response); response=null; } var scrollTop=getScrollPosition(); gotoTop.style.display = "none"; if(0!=scrollTop.top) { if(scrollTop.top+client_h>=max_height) { gotoTop.childNodes[0].style.bottom=scrollTop.top+client_h-max_height+"px"; if(Browser.isIE6 && scrollTop.top+client_h>=max_height-1) { gotoTop.childNodes[0].style.bottom=scrollTop.top+client_h-max_height-1+"px"; } gotoTop.style.display = "block"; } else { if(Browser.isIE6) { response=setTimeout(function(){gotoTop.childNodes[0].style.bottom=0+"px";gotoTop.style.display = "block";},200); } else { gotoTop.childNodes[0].style.bottom=0+"px";gotoTop.style.display = "block"; } } } } function resizeEvent() { client_h = document.documentElement.clientHeight || document.body.clientHeight || 0; collectScroll(); } window.οnscrοll=collectScroll; window.οnresize=resizeEvent;