JS14 平滑滚动

scroll-behavior

使用CSS3的scroll-behavior: smooth属性可以轻松的实现平滑滚动:

<head>
  <style>
    html, body {
      scroll-behavior: smooth;
    }
  </style>
</head>
<body>
<div id="head">Head</div>
<div class="scroll-x"><img src="./default.png"></div>
<div class="scroll-x"><img src="./default.png"></div>
<div class="scroll-x"><img src="./default.png"></div>
<div class="scroll-x"><img src="./default.png"></div>
<div class="scroll-x"><img src="./default.png"></div>
<div class="scroll-x"><img src="./default.png"></div>
<a href="#head">Back to Top</a>
</body>

兼容性:

scroll-nap-type

scroll-nap-type属性可以在移动端实现平滑定位滚动:

<head>
  <style>
    .scroll-x {
    width: 300px;
    scroll-snap-type: x mandatory;
    white-space: nowrap;
    overflow: auto;
}

.scroll-x img {
    scroll-snap-align: start;
}
  </style>
</head>

<body>
  <div class="scroll-x">
    <img src="./mm.jpg">
    <img src="./mm2.jpg">
    <img src="./mm3.jpg">
    <img src="./mm4.jpg">
    <img src="./mm5.jpg">
  </div>
</body>

图片左边缘会和滚动容器的左边缘进行吸附,它的作用是让页面滚动停留在你希望用户关注的重点区域(要注意,在IOS浏览器下需要同时设置滚动容器-webkit-overflow-scrolling:touch

详细的属性介绍可以参考张鑫旭的文章

要注意的是,虽然Scroll Snap可以让网页容器滚动停止的时候,自动平滑定位到指定元素,但是它的真正的作用是元素定位增强,想要使用平滑滚动,还是应该使用上一个属性scroll-behavior

scrollIntoView

除了CSS属性,也可以使用JavaScript来实现平滑滚动。DOM元素的scrollIntoView()方法是一个支持IE6的原生API,它可以让当前的元素滚动到浏览器窗口的可视区域内。

element.scrollIntoView(); // 等同于element.scrollIntoView(true) 
element.scrollIntoView(alignToTop); // Boolean型参数 
element.scrollIntoView(scrollIntoViewOptions); // Object型参数

它可以接受一个布尔值alignToTop作为参数,如果为true(默认值),元素的顶端将和其所在的可视区域的顶端对齐,对应的scrollIntoViewOptions属性是{block: "start", inline: "nearest"};如果是false,元素的底端将和其所在滚动区的可视区域底端平齐,对应的scrollIntoViewOptions属性是{block: "end", inline: "nearest"}

如果参数是一个对象(有可能不被浏览器支持),那么可以取三个属性:

  • behavior,定义滚动效果
  • bloack,定义垂直对齐方向
  • inline,定义水平对齐方向
if (choice === 'exit') {
  document.getElementById(`question${unmarkedIndex}`).scrollIntoView(true)
}

各个浏览器均支持scrollIntoView,而且兼容性也不错:

除此之外还有几个属性不是所有浏览器都实现的方法:

(1)scrollIntoViewIfNeeded(alignCenter)

只在当前元素在视窗的可见范围内不可见的情况下,才滚动浏览器窗口或容器元素,最终让当前元素可见。

如果当前元素在视窗中可见,这个方法不做任何处理。如果将可选参数alignCenter设置为true,则表示尽量将元素显示在视窗中部(垂直方向)

(2)scrollByLines(lineCount)

将元素的内容滚动指定的行数的高度,lineCount的值可以为正值或是负值。

(3)scrollByPages(pageCount)

将元素的内容滚动指定的页面的高度,具体高度由元素的高度决定。

scrollIntoView()scrollIntoVIewIfNeeded()作用的是元素的窗口,而scrollByLines()scrollByPages()影响元素自身。

可以看出来,只有scrollIntoView的兼容性比较广泛,其他几种方法都只有某几个浏览器实现了,所以不推荐使用。

向下兼容

如果不使用上述方法,也可以在requestAnimationFrame中手动修改scrollTop的值来实现:

/**
 * @description 页面垂直平滑滚动到指定滚动高度
 * @author 张鑫旭
*/
const scrollSmoothTo = function(position) {
  // 当前滚动高度
  let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  // 滚动step方法
  const step = function() {
    // 距离目标滚动距离
    const distance = position - scrollTop;
    // 目标滚动位置
    scrollTop = scrollTop + distance / 5;
    if (Math.abs(distance) < 1) {
      window.scrollTo(0, position);
    } else {
      window.scrollTo(0, scrollTop);
      
      requestAnimationFrame(step);
    }
  };
  step();
};

scrollSmoothTo(0); // 网页平滑滚动到顶部

可以根据下面的代码对浏览器是否支持scrollBehavior

if (typeof window.getComputedStyle(document.body).scrollBehavior === 'undefined') {
   // 传统的JS平滑滚动处理代码...
}

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值