scroll-behavior & scrollIntoView 的使用,以及解决ios手机不兼容的问题

5,907 阅读4分钟

前言

在平时的日常开发中,我们可能会遇到这样的需求,点击一个导航链接,页面会定位到一个元素或上去。如下图vue官网所示,我点击左侧导航栏链接,右边会定位到相应的位置。

2.gif

但是这种定位效果过于生硬,没有平滑滚动的效果,直接用锚点的形式就能实现。如果我们需要有平滑滚动的效果,就得自己去写滚动效果,不仅效率不高可能效果还不太理想。所以,今天就给大家介绍一下css中的scroll-behavior属性和js中的scrollIntoViewAPI,以及相关兼容性问题。

一、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;
}

实现效果如下图:当我点击相应链接时,底部区域就平滑滚动到了相应的位置。

1.gif

缺点

  1. 不能自定义元素顶端对齐方式,默认是元素的顶端将和其所在滚动区的可视区域的顶端对齐。
  2. 兼容性问题,下图是浏览器兼容性

image.png

经本人测试,对于移动端,安卓的兼容性还是很好的,ios手机上的浏览器几乎都不支持平滑滚动效果,定位效果非常生硬,效果如下图所示:

IMG_3634.GIF

如果对兼容性要求不太高,那么该css属性还是能满足大多数场景的。但有的时候,我们就是想要ios手机也能兼容平滑滚动效果,对此,我们可以使用js中的scrollIntoViewsmoothscroll-polyfill插件解决该问题。

二、scrollIntoView

它的作用跟scroll-behavior属性是一样的,只不过是用js去实现,并且实现的效果更多。

参数

  1. alignToTop(可选)
    • 值为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐
    • 值为false,元素的底端将和其所在滚动区的可视区域的底端对齐
  2. scrollIntoViewOptions(可选) 该参数为对象形式
    • behavior(可选):定义动画过渡效果, 值为 auto或 smooth 之一。默认为 auto
    • block(可选):定义垂直方向的对齐, 值为 startcenterend, 或 nearest之一。默认为 start
    • inline(可选):定义水平方向的对齐, 值为 startcenterend, 或 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>

下图是演示效果:

2.gif

scroll-behavior属性实现的效果是一样的,只不过它有更多效果可供选择。

缺点

它的缺点主要还是兼容性问题,兼容性也不是很好,浏览器兼容性如下:

image.png

在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手机上看看实现效果,效果如下:

IMG_3636.GIF

以上就是关于css中的scroll-behavior属性和js中的scrollIntoViewAPI使用方法,以及如何解决ios手机兼容性的问题。是不是觉得还是挺实用的,不知道的同学可以去手动实践实践哦。