原生Javascript实现页面平滑滚动跳转

看见很多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 本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。

2 关于 “原生Javascript实现页面平滑滚动跳转” 的评论

    1. Brain 文章作者

      这本来就是有过度的。修改最后一段的缓冲公式里的数值,或者修改setInterval的时间值,就可以改速度

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注