html滚动的秘密

前言

今天偶然发现一个从没见过的原生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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值