前言
今天偶然发现一个从没见过的原生api :scrollIntoView(),遂去查询了MDN。原来是 Element.scrollIntoView() 方法让当前的元素滚动到浏览器窗口的可视区域内。
于是又跑回去研究了一番html滚动效果,下面是三个测试案例
小测试案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
html, body{
padding:0;
margin:0;
}
.box > div{
height: 500px;
background: #a4ff42;
color: #fff;
text-align: center;
line-height: 500px;
}
.box > .box2{
background: #111111;
}
.box > .box3{
background: #1234456;
}
.box > .box4{
background: #222333;
}
.box > .box5{
background: #aacc11;
}
.box > .box6{
background: #a4f555;
}
.fix{
position: fixed;
top:0;
}
.fix a{
margin-right: 20px;
}
.fix2{
position: fixed;
top:100px;
}
.fix2 button{
margin-right: 20px;
}
.fix3{
position: fixed;
top:200px;
}
.fix3 button{
margin-right: 20px;
}
</style>
</head>
<body>
<div class="fix">
<h4>a标签跳转</h4>
<a href="#box1"><button>111</button></a>
<a href="#box2"><button>222</button></a>
<a href="#box3"><button>333</button></a>
<a href="#box4"><button>444</button></a>
<a href="#box5"><button>555</button></a>
<a href="#box6"><button>666</button></a>
</div>
<div class="fix2" id="fix2">
<h4>scrollIntoView 跳转</h4>
<button data-id="box1">111</button>
<button data-id="box2">222</button>
<button data-id="box3">333</button>
<button data-id="box4">444</button>
<button data-id="box5">555</button>
<button data-id="box6">666</button>
</div>
<div class="fix3" id="fix3">
<h4>scroll滚动到目标元素</h4>
<button data-id="box1">111</button>
<button data-id="box2">222</button>
<button data-id="box3">333</button>
<button data-id="box4">444</button>
<button data-id="box5">555</button>
<button data-id="box6">666</button>
</div>
<div class="box">
<div class="box1" id="box1">111</div>
<div class="box2" id="box2">222</div>
<div class="box3" id="box3">333</div>
<div class="box4" id="box4">444</div>
<div class="box5" id="box5">555</div>
<div class="box6" id="box6">666</div>
</div>
<script>
// 通过scrollIntoView跳转到目标元素视口
document.getElementById("fix2").onclick = function(e){
// console.log(e)
var targetId = e.srcElement.dataset.id
if(targetId){
document.getElementById(targetId).scrollIntoView();
}
}
// 通过scroll 滚动到目标元素视口
document.getElementById("fix3").onclick = function(e){
// console.log(e)
var targetId = e.srcElement.dataset.id
if(targetId){
var el = document.getElementById(targetId);
var elTop = el.offsetTop;
scrollFunc(elTop, "linner");
}
}
/**
* 滚动函数
* @param elTop Number 目标元素的scrollTop
* @param type String 滚动类型 默认为slow : 减速滚动 quicken : 加速滚动 linner : 匀速滚动
*/
function scrollFunc(elTop, type){
// 获取文档scrollTop
var docuTop = document.documentElement.scrollTop;
// 计算目标元素scrollTop与当前文档scrollTop差值
var diff = elTop - docuTop;
// 速度 定时器滚动的最小距离
var speed = 1;
// 时间 定时器滚动的时间
var timer = 10;
// 获取差值数组
var speedList = getNumList(diff, speed, 5);
if(type === 'quicken'){
speedList = speedList.reverse();
}else if(type === 'slow'){
speedList = speedList;
}else if(type === 'linner'){
speedList = speedList.map(item=> Math.abs(diff)/speedList.length);
}
var i = 0;
scroll(docuTop, i);
// 滚动函数
function scroll(docuTop, i){
setTimeout(function(){
if(diff > 0){
// 最后一次滚动的距离判定
if( i < speedList.length){
document.documentElement.scrollTop = docuTop + speedList[i];
i++;
scroll(document.documentElement.scrollTop, i)
}else{
document.documentElement.scrollTop = elTop;
}
}else{
// 最后一次滚动的距离判定
if( i < speedList.length){
document.documentElement.scrollTop = docuTop - speedList[i];
i++;
scroll(document.documentElement.scrollTop, i)
}else{
document.documentElement.scrollTop = elTop;
}
}
},timer)
}
}
/**
* 获取差值数组
* @params Num Number 差值目标
* @params Min Number 差值目标最小范围值
* @params Dvalue Number 差值比例
* */
function getNumList (Num, Min, Dvalue){
var NumList = [];
var Num = Math.abs(Num);
except(Num, Min);
// 除以二
function except(nowNum, Min){
if(nowNum > Min){
NumList.push(nowNum/Dvalue);
var remainder = nowNum - nowNum/Dvalue;
except(remainder, Min);
}else{
NumList.push(nowNum);
}
}
return NumList;
}
</script>
</body>
</html>