#用js源码制作一个通用的TOP按钮
##效果:超过一屏显示按钮,平滑,美观的滑动到顶部,且按钮消失
最近迎来了我的第一个上线项目,虽然我做的几个页面都算是比较简单的静态页面再加上一些动态数据加载和交互,可还是发现了不少的问题,其中尤其发现目前对DOM相关的一些属性理解不到位,本着把他搞清楚弄明白的宗旨,这几天都在爬贴找资料,现在就把它总结一下,可能有许多从网上贴的,还有就是关于一些详细的兼容性问题,根据自己的需求加代码,我这里只兼容IE8以上
1.由于其中一个页面较长需要加入TOP按钮, 因此我第一个想到的是利用锚链,可是犹豫做出的效果很生硬,不平滑,所以被我果断放弃了。
2.接下来goole了一下,大部分都是用jQuery做出来的,可是我们这个项目的类库都是我们自己写的一些微型类库,没有涉及到这一块儿,因此我也只能自己想办法用JS源码解决了。
3.html里面给个top按钮,你用input也行,普通的div或span也好,我是给了一个
<div id="backTop"></div>
4.样式问题我这里就不赘述了,至于你想用图片做的很美观,还是用hover做的简单炫丽都随你了
5.接下来是正题,是我们主要功能实现部分,现在先把一些涉及的知识点给罗列一下(可能只是用到一部分,但为了能弄明白,还是对比理解一下):

①元素的offsetWidth/offsetHeight对应的是盒模型宽度和高度,这两个值跟我们在浏览器审查元素中得到的值是一致的,包含了border,和padding以及width/height;
②clientWidth/clientHeight对应的是除去border后的那部分区域的宽度和高度,不包含滚动条的宽度,只包含content和padding;
③scrollWidth/scrollHeight对应的滚动区域的宽度和高度,但是不包含滚动条的宽度,滚动区域是由padding和content组成。在谷歌下,如果内容高度小于可视区高度,则scrollHeight等于可视区高度
④window.innerWidth/window.innerHeight 在IE下描述为document.documentElement.clientWidth/Height(在标准浏览器下,这种写法通用)—->>窗口的可视区域
⑤scrollTop/scrollLeft在IE下描述为document.documentElement.scrollTop/Left在标准浏览器下为window.pageXOffset/window.pageYoffset
⑥offsetParent:离当前节点最近的具有定位属性的祖先节点,若祖先节点没有定位属性,offsetParent以body为准,若当前节点有display:none;属性,则offsetParent为null
⑦offsetTop/offsetLeft 当前节点到离自己最近的offsetParent的距离
下面是验证代码:(测试环境chrome)
html代码块儿
<div id="box">
<div id="testbox"></div>
</div>
css代码块儿
body{
margin: 0;
}
#box{
width: 400px;
height: 250px;
position: relative;
padding:20px;
margin: 50px;
background-color: lightgreen;
border:30px solid red;
}
#testbox{
width: 200px;
height: 100px;
padding: 40px 30px 10px 20px;
margin: 20px 10px 30px 40px;
position: absolute;
top: 30px;
left:60px;
background-color: lightblue;
border:20px solid yellow;
}
js代码块儿
var box = document.getElementById('box');
var testBox = document.getElementById('testbox');
console.log(window.innerWidth,window.innerHeight); //1398,378
console.log(document.documentElement.clientWidth,document.documentElement.clientHeight); //1398,378
console.log(document.documentElement.scrollTop,document.documentElement.scrollLeft);//0,0
console.log(box.offsetWidth,box.offsetHeight);//500,350
console.log(testBox.offsetWidth,testBox.offsetHeight);//290,190
console.log(box.scrollWidth,box.scrollHeight);//440,290
console.log(testBox.scrollWidth,testBox.scrollHeight);//250,150
console.log(box.clientWidth,box.clientHeight);//440,290
console.log(testBox.clientWidth,testBox.clientHeight);//250,150
console.log(box.scrollTop,box.scrollLeft);//0,0
console.log(testBox.scrollTop,testBox.scrollLeft);//0,0
console.log(box.offsetTop,box.offsetLeft);//50,50
console.log(testBox.offsetTop,testBox.offsetLeft);//50,100
console.log(box.offsetParent,testBox.offsetParent);//<body></body>,<div id="box">…</div>
测试结果图示:


##涉及的定时器等有关知识点回头陆续更新,下面是有关JS源码解决TOP按钮的代码及注释
var oBtn = document.getElementById('backtop'); //标签获取 这个标签是你获取自己的document文档中的top标签下面的
根据自己需要改动也可以完全一样这个随你自由了
var clientHeight = document.documentElement.clientHeight; //获取页面可视区高度
var timer = null;
var isTop = true; //初始值即滚动条在顶端时为true
window.onscroll = function () { //滚动条滚动触发
var osTop = document.documentElement.scrollTop || document.body.scrollTop;//获取滚动条距离顶部的距离
if (osTop >= clientHeight) {
oBtn.style.opacity = 1; //大于一屏让top按钮显示出来
}
else{
oBtn.style.opacity = 0; //小于一屏让top按钮消失
}
if (!isTop) {
clearInterval(timer); //如果
}
isTop = false; //滚动触发时istop变为false
}
oBtn.onclick = function (){ //事件绑定
timer = setInterval(function(){ //设置定时器
var osTop = document.documentElement.scrollTop || document.body.scrollTop;//获取滚动条距离顶部的距离
var ispeed = Math.floor(-osTop / 5); //向下取整 每次回到顶端都留有4px,原因未知
document.documentElement.scrollTop = document.body.scrollTop = osTop + ispeed; //使滚动由快变慢
isTop = true; //点击完之后回到顶端 istop为true
if (osTop == 0) { //每次滚动条到顶部清除定时器
clearInterval(timer);
}
},30);
}
至此平滑滚动的按钮就这样easy的写出来了