前言
在平时的日常开发中,我们可能会遇到这样的需求,点击一个导航链接,页面会定位到一个元素或上去。如下图vue官网所示,我点击左侧导航栏链接,右边会定位到相应的位置。
但是这种定位效果过于生硬,没有平滑滚动的效果,直接用锚点的形式就能实现。如果我们需要有平滑滚动的效果,就得自己去写滚动效果,不仅效率不高可能效果还不太理想。所以,今天就给大家介绍一下css中的scroll-behavior
属性和js中的scrollIntoView
API,以及相关兼容性问题。
一、scroll-behavior
MDN上是这么介绍该css属性的:当用户手动导航或者 CSSOM scrolling API 触发滚动操作时,css属性 scroll-behavior
为一个滚动框指定滚动行为,其他任何的滚动,例如那些由于用户行为而产生的滚动,不受这个属性的影响。在根元素中指定这个属性时,它反而适用于视窗。
值
该属性有2个值可选
- auto : 滚动框立即滚动,即默认效果,没有平滑滚动效果
- smooth : 有平滑滚动效过
例子
html代码
<div>
<a href="#A">A</a>
<a href="#B">B</a>
<a href="#C">C</a>
</div>
<scroll-container>
<scroll-page id="A">A</scroll-page>
<scroll-page id="B">B</scroll-page>
<scroll-page id="C">C</scroll-page>
</scroll-container>
css代码
a {
display: inline-block;
width: 50px;
font-size: 30px;
text-decoration: none;
}
a:hover {
color: #f00;
}
scroll-container {
display: block;
width: 350px;
height: 200px;
overflow-y: scroll;
scroll-behavior: smooth;
}
scroll-page {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 5em;
}
实现效果如下图:当我点击相应链接时,底部区域就平滑滚动到了相应的位置。
缺点
- 不能自定义元素顶端对齐方式,默认是元素的顶端将和其所在滚动区的可视区域的顶端对齐。
- 兼容性问题,下图是浏览器兼容性
经本人测试,对于移动端,安卓的兼容性还是很好的,ios手机上的浏览器几乎都不支持平滑滚动效果,定位效果非常生硬,效果如下图所示:
如果对兼容性要求不太高,那么该css属性还是能满足大多数场景的。但有的时候,我们就是想要ios手机也能兼容平滑滚动效果,对此,我们可以使用js中的scrollIntoView
和smoothscroll-polyfill
插件解决该问题。
二、scrollIntoView
它的作用跟scroll-behavior
属性是一样的,只不过是用js去实现,并且实现的效果更多。
参数
- alignToTop(可选)
- 值为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐
- 值为false,元素的底端将和其所在滚动区的可视区域的底端对齐
- scrollIntoViewOptions(可选) 该参数为对象形式
behavior
(可选):定义动画过渡效果, 值为auto
或smooth
之一。默认为auto
。block
(可选):定义垂直方向的对齐, 值为start
,center
,end
, 或nearest
之一。默认为start
。inline
(可选):定义水平方向的对齐, 值为start
,center
,end
, 或nearest
之一。默认为nearest
。
语法
let ele = document.getElementById("container");
ele.scrollIntoView(); // 等同于ele.scrollIntoView(true)
ele.scrollIntoView(false);
ele.scrollIntoView({block: "end"});
ele.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
例子
该例子是在vue中演示的,代码非常简单。
<template>
<div>
<div>
<a @click="moveToPosition('A')">A</a>
<a @click="moveToPosition('B')">B</a>
<a @click="moveToPosition('C')">C</a>
</div>
<div class="scroll-container">
<h1 id="A">A</h1>
<h1 id="B">B</h1>
<h1 id="C">C</h1>
</div>
</div>
</template>
<script>
export default {
methods: {
moveToPosition(ele) {
this.$el
.querySelector(`#${ele}`)
.scrollIntoView({ block: "start", behavior: "smooth" });
},
},
}
</script>
<style scoped lang="less">
a {
display: inline-block;
width: 50px;
font-size: 30px;
text-decoration: none;
&:hover {
color: #f00;
}
}
.scroll-container {
display: block;
width: 350px;
height: 200px;
overflow-y: scroll;
}
h1 {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 5em;
}
</style>
下图是演示效果:
与scroll-behavior
属性实现的效果是一样的,只不过它有更多效果可供选择。
缺点
它的缺点主要还是兼容性问题,兼容性也不是很好,浏览器兼容性如下:
在ios手机上,一样会没有平滑滚动效果.但是,我们可以借助一个第三方插件,能够使ios手机支scrollIntoView
的平滑滚动效果,那就是smoothscroll-polyfill
。
三、smoothscroll-polyfill插件
安装
# npm
npm install smoothscroll-polyfill --save
# yarn
yarn add smoothscroll-polyfill
引入
在你使用了scrollIntoView
的地方引入该插件.
import smoothscroll from 'smoothscroll-polyfill'
使用
在你的实现定位的方法里写上以下代码
smoothscroll.polyfill();
按照以上方式,我们可以改下刚才的代码,使ios手机支持平滑滚动效果,只需要改动js部分即可。
<script>
import smoothscroll from 'smoothscroll-polyfill';
export default {
methods: {
moveToPosition(ele) {
smoothscroll.polyfill();
this.$el
.querySelector(`#${ele}`)
.scrollIntoView({ block: "start", behavior: "smooth" });
},
},
}
</script>
效果
接下来在ios手机上看看实现效果,效果如下:
以上就是关于css中的scroll-behavior
属性和js中的scrollIntoView
API使用方法,以及如何解决ios手机兼容性的问题。是不是觉得还是挺实用的,不知道的同学可以去手动实践实践哦。