JS scrollIntoView 技巧揭秘:解锁网页流畅交互

文章目录

一.基本概念

  • scrollIntoView是 JavaScript 中用于滚动元素,使其进入浏览器视口(viewport)的一个方法。它是Element接口的一个方法,这意味着可以在任何 DOM 元素上调用它。
  • 例如,CSDN 中点击目录点位到相应的位置。

二.语法和参数

基本语法:element.scrollIntoView();

这里的element是要滚动到可视区域的目标元素。这个方法可以接受一个可选的参数,这个参数是一个对象,用于更精细地控制滚动行为。

例如:element.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });

参数详解:

  • behavior :用于指定滚动行为的类型。它有两个可能的值:
    • auto(默认值):滚动立即发生,没有过渡动画效果。
    • smooth:滚动以平滑的动画效果进行,这种效果在现代浏览器中提供了更好的用户体验。
  • block :用于确定元素在垂直方向(块轴)上相对于视口的对齐方式。它有以下几个可能的值:
    • start(默认值):将元素的顶部与视口的顶部对齐。
    • center:将元素的中心与视口的中心对齐。
    • end:将元素的底部与视口的底部对齐。
    • nearest:将元素滚动到离其最近的边缘与视口对应的边缘对齐。
  • inline :用于确定元素在水平方向(行内轴)上相对于视口的对齐方式。它也有和block类似的值,如startcenterendnearest,其含义和在垂直方向上类似,只是作用于水平方向。

三.应用场景和示例

场景一:点击目录点位到相应的位置

以下实现了一个带有导航目录的页面布局,当用户点击目录中的标题时,页面会平滑滚动,使对应内容区域展示在可视范围内,方便用户快速定位到感兴趣的部分,适用于内容较长的页面场景。

React 示例代码:

目录

js 复制代码
|-- 文件夹
|--- index.jsx
|--- index.module.less

代码

jsx 复制代码
import less from './index.module.less'

const ScrollView = () => {
  const TabsArr = [
    {
      id: 1,
      title: 'menu1',
      childrenNum: 2
    },
    {
      id: 2,
      title: 'menu2',
      childrenNum: 3
    },
    {
      id: 3,
      title: 'menu3',
      childrenNum: 5
    },
    {
      id: 4,
      title: 'menu4',
      childrenNum: 7
    },
    {
      id: 5,
      title: 'menu5',
      childrenNum: 9
    },
    {
      id: 6,
      title: 'menu6',
      childrenNum: 6
    }
  ]

  const recordScroll = record => {
    const dom = document.getElementById(record.title)
    if (dom) {
      dom.scrollIntoView({
        behavior: 'smooth',
        block: 'start',
        inline: 'start'
      })
    }
  }

  return (
    <div className={less.scrollViewBox}>
      <div className={less.menuBox}>
        <div className={less.title}>目录</div>
        {TabsArr.map(item => {
          return (
            <div key={item.id} className={less.item} onClick={() => recordScroll(item)}>
              {item.title}
            </div>
          )
        })}
      </div>
      <div className={less.pageContent}>
        {TabsArr.map(item => {
          return (
            <div key={item.id} className={less.item} id={item.title}>
              {Array.from({ length: item.childrenNum }).map((it, index) => {
                return (
                  <div key={index} className={less.children}>
                    {item.title + '-' + index}
                  </div>
                )
              })}
            </div>
          )
        })}
      </div>
    </div>
  )
}

export default ScrollView
less 复制代码
.scrollViewBox {
  width: 1000px;
  height: 800px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  position: relative;

  .menuBox {
    width: 200px;
    background-color: #f0f2f5;
    padding: 10px 20px;
    box-sizing: border-box;
    position: absolute;
    top: 0;
    right: -205px;

    .title {
      font-size: 16px;
      color: #333;
      font-weight: bold;
      margin-bottom: 15px;
      padding-bottom: 15px;
      border-bottom: 1px solid black;
    }

    .item {
      font-size: 14px;
      color: #333;
      margin-bottom: 10px;
      cursor: pointer;

      &:hover {
        color: red;
      }
    }
  }

  .pageContent {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    overflow-y: auto;

    .item {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      margin-bottom: 100px;

      .children {
        width: 200px;
        height: 200px;
        text-align: center;
        line-height: 200px;
        background-color: #f0f2f5;
        margin: 20px;
      }
    }
  }
}
Vue3 示例代码:
Vue 复制代码
<template>
  <div class="scrollViewBox">
    <div class="menuBox">
      <div class="title">目录</div>
      <div v-for="(item, index) in TabsArr" :key="item.id" class="item" @click="recordScroll(index)">
        {{ item.title }}
      </div>
    </div>
    <div class="pageContent">
      <div v-for="(item) in TabsArr" :key="item.id" :id="item.title" class="item">
        <div v-for="(it, subIndex) in Array(item.childrenNum).fill(0)" :key="subIndex" class="children">
          {{ item.title + '-' + subIndex }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>

const TabsArr = [
  {
    id: 1,
    title: 'menu1',
    childrenNum: 2,
  },
  {
    id: 2,
    title: 'menu2',
    childrenNum: 3,
  },
  {
    id: 3,
    title: 'menu3',
    childrenNum: 5,
  },
  {
    id: 4,
    title: 'menu4',
    childrenNum: 7,
  },
  {
    id: 5,
    title: 'menu5',
    childrenNum: 9,
  },
  {
    id: 6,
    title: 'menu6',
    childrenNum: 6,
  },
]

const recordScroll = (index) => {
  const dom = document.getElementById(TabsArr[index].title)
  if (dom) {
    dom.scrollIntoView({
      behavior: 'smooth',
      block: 'start',
      inline: 'start',
    })
  }
}
</script>

<style scoped>
.scrollViewBox {
  width: 1000px;
  height: 800px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  position: relative;
}

.menuBox {
  width: 200px;
  background-color: #f0f2f5;
  padding: 10px 20px;
  box-sizing: border-box;
  position: absolute;
  top: 0;
  right: -205px;
}

.title {
  font-size: 16px;
  color: #333;
  font-weight: bold;
  margin-bottom: 15px;
  padding-bottom: 15px;
  border-bottom: 1px solid black;
}

.item {
  font-size: 14px;
  color: #333;
  margin-bottom: 10px;
  cursor: pointer;
}

.item:hover {
  color: red;
}

.pageContent {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  overflow-y: auto;
}

.item {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin-bottom: 100px;
}

.children {
  width: 200px;
  height: 200px;
  text-align: center;
  line-height: 200px;
  background-color: #f0f2f5;
  margin: 20px;
}
</style>

场景二:轮播图定位到指定图片

在图片轮播组件中,通常会有底部的导航小圆点或者图片标题等元素,用于指示和切换不同的图片。当用户点击这些导航元素时,除了切换图片显示,还希望图片所在的轮播区域能自动滚动到可视范围,让用户清晰看到当前选中的图片。

示例代码
jsx 复制代码
import React, { useState } from 'react'
import './Carousel.css'

const Carousel = () => {
  const images = [
    { id: 1, src: 'image1.jpg', title: 'Image 1' },
    { id: 2, src: 'image2.jpg', title: 'Image 2' },
    { id: 3, src: 'image3.jpg', title: 'Image 3' }
  ]
  const [currentIndex, setCurrentIndex] = useState(0)

  const scrollToImage = index => {
    const imageElement = document.getElementById(`image-${index}`)
    if (imageElement) {
      imageElement.scrollIntoView({
        behavior: 'smooth'
      })
    }
    setCurrentIndex(index)
  }

  return (
    <div className="carousel-container">
      <div className="carousel-images">
        {images.map((image, index) => (
          <img
            key={image.id}
            id={`image-${index}`}
            src={image.src}
            alt={image.title}
            className="carousel-image"
          />
        ))}
      </div>
      <div className="carousel-nav">
        {images.map((image, index) => (
          <span
            key={index}
            className={`nav-dot ${index === currentIndex ? 'active' : ''}`}
            onClick={() => scrollToImage(index)}
          ></span>
        ))}
      </div>
    </div>
  )
}

export default Carousel
css 复制代码
.carousel-container {
  width: 800px;
  height: 400px;
  overflow: hidden;
  position: relative;
}

.carousel-images {
  width: fit-content;
  height: 100%;
  display: flex;
  transition: transform 0.5s ease;
}

.carousel-image {
  width: 800px;
  height: 100%;
  object-fit: cover;
}

.carousel-nav {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
}

.nav-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #ccc;
  margin-right: 5px;
  cursor: pointer;
}

.nav-dot.active {
  background-color: #333;
}
相关推荐
呆头呆脑~13 分钟前
逆向 易九批 最新版 爬虫逆向 x-sign ......
javascript·爬虫·python·算法·网络爬虫
Xudde.13 分钟前
HTML中meta的用法
java·前端·javascript·笔记·html
傻小胖1 小时前
react的statehook useState Hook详细使用
前端·javascript·react.js
).(1 小时前
el-table横向滚动条,滚动后消失
前端·css·css3
微臣酒驾来迟1 小时前
el-descriptions-item使用span占行不生效
前端·javascript·vue.js
明月看潮生2 小时前
青少年编程与数学 02-006 前端开发框架VUE 22课题、状态管理
前端·javascript·vue.js·青少年编程·编程与数学
禾小毅2 小时前
vue 实现打包并同时上传至服务器端
前端·vue.js
Front_Yue2 小时前
Vue虚拟DOM:如何提高前端开发效率
前端·javascript·vue.js
Super毛毛穗2 小时前
Vue3学习总结
javascript·vue.js·学习
林涧泣2 小时前
【Uniapp-Vue3】组合式API中的组件的生命周期函数(钩子函数)
前端·javascript·uni-app