看见很多Blog的右下角有一个平滑滚动到页面顶部的箭头,觉得挺实用。我的WP主题没有自带这个功能,网上找到的现成的又都是基于jQuery的,自己的网站我还不考虑用任何JS框架,自己写一个好了…既然是自己写那就考虑把功能写得完整一些,不仅要可以平滑滚动到页面顶端,而且要可以平滑滚动到页面任何元素指定的位置,实现锚点的功能。
先把那个箭头按钮给造出来,一个黑方块里面套一个三角形和正方形,一共3个元素:
1 2 3 4 | <a id="returnTop" href="###" onclick="scrollPosition()"><!--scrollPosition就是跳转调用的函数--> <span id="returnTop_a"></span> <span id="returnTop_b"></span> </a> |
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #returnTop { background-color:#333; width:40px; height:40px; display:block; position:fixed; line-height:50px; color:#fff; right:30px; bottom:30px; } #returnTop_a{ position: absolute; top: -2px; left: 8px; width: 0; height: 0; border-width: 10px 12px; border-style: dashed dashed solid; border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) #FFF; } #returnTop_b{ position: absolute; top: 18px; left: 14px; width: 12px; height: 12px; background: #FFF; } |
接下来就是JS部分了,从犀牛书上搬来两个有用的函数,都已做好兼容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | function getScrollOffsets(_w) {//获取页面的滚动位置 _w = _w || window; //for all and IE9+ if (_w.pageXOffset != null) return { x: _w.pageXOffset, y: _w.pageYOffset }; //for IE678 var _d = _w.document; if (document.compatMode == "CSS1Compat") return { //for IE678 x: _d.documentElement.scrollLeft, y: _d.documentElement.scrollTop }; //for other mode return { x: _d.body.scrollLeft, y: _d.body.scrpllTop }; } function getViewPortSize(_w) {//获取页面的窗口大小 _w = _w || window; //for all and IE9+ if (_w.innerWidth != null) return { x: _w.innerWidth, y: _w.innerHeight }; //for IE678 var _d = _w.document; if (document.compatMode == "CSS1Compat") return { //for IE678 x: _d.documentElement.clientWidth, y: _d.documentElement.clientHeight }; //for other mode return { x: _d.body.clientWidth, y: _d.body.clientHeight }; } |
最后是主程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | function scrollPosition(_obj) {//参数_obj可以是任何页面上存在的元素的id,或者是指定元素本身 var targetX, targetY; if (!_obj) { //如果不指定锚点元素,就跳到页面顶端0,0位置 targetX = 0; targetY = 0; } else { if (typeof (_obj) == "string") { _obj = document.getElementById(_obj); } else { _obj = _obj } targetX = _obj.getBoundingClientRect().left + getScrollOffsets().x; targetY = _obj.getBoundingClientRect().top + getScrollOffsets().y; } //如果目标元素的位置在最后一屏,那就指定目标位置为页面底部 //如果目标元素的位置为负数,就指定目标位置为页面顶部 var maxTargetX=document.body.scrollWidth-getViewPortSize().x; if(targetX>=maxTargetX) targetX=maxTargetX; if(targetX<0) targetX=0; var maxTargetY=document.body.scrollHeight-getViewPortSize().y; if(targetY>=maxTargetY) targetY=maxTargetY; if(targetY<0) targetY=0; var tempTimer = setInterval(function () { var currentY = getScrollOffsets().y; var currentX = getScrollOffsets().x; //跳转位置的缓冲公式 var tempTargetY = currentY - (currentY - targetY) / 10; var tempTargetX = currentX - (currentX - targetX) / 10; //由于缓冲公式会生成小数,而scrollTo函数会省略小数点后面的数字,所以要对跳转的坐标做一些微调 if (Math.abs(tempTargetY - currentY) < 1) { tempTargetY - currentY > 0 ? tempTargetY++ : tempTargetY--; } if (Math.abs(tempTargetX - currentX) < 1) { tempTargetX - currentX > 0 ? tempTargetX++ : tempTargetX--; } //页面跳转 window.scrollTo(tempTargetX, tempTargetY); //到达指定位置后清除一下Interval if ( Math.abs(getScrollOffsets().y - targetY) <= 2 && Math.abs(getScrollOffsets().x - targetX) <= 2 ) { clearInterval(tempTimer); window.scrollTo(targetX, targetY); //console.log("done"); } }, 10); } |
可以调用以下命令任意平滑滚动到指定的元素位置:
scrollPosition("itemId");
本程序兼容性: IE7+以及所有其他浏览器的当前版本(不兼容IE6)
附上jsfiddle演示地址:http://jsfiddle.net/BrainShi/B3mZV/
本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/410.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。
我想加个时间来过渡,怎么实现呢?
这本来就是有过度的。修改最后一段的缓冲公式里的数值,或者修改setInterval的时间值,就可以改速度