文章目录
- 一.基本概念
- 二.语法和参数
- 基本语法:`element.scrollIntoView();`
- 参数详解:
- 三.应用场景和示例
- 场景一:点击目录点位到相应的位置
- React 示例代码:
- Vue3 示例代码:
- 场景二:轮播图定位到指定图片
- 示例代码
一.基本概念
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
类似的值,如start
、center
、end
、nearest
,其含义和在垂直方向上类似,只是作用于水平方向。
三.应用场景和示例
场景一:点击目录点位到相应的位置
以下实现了一个带有导航目录的页面布局,当用户点击目录中的标题时,页面会平滑滚动,使对应内容区域展示在可视范围内,方便用户快速定位到感兴趣的部分,适用于内容较长的页面场景。
React 示例代码:
目录
|-- 文件夹
|--- index.jsx
|--- index.module.less
代码
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
.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 示例代码:
<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>
场景二:轮播图定位到指定图片
在图片轮播组件中,通常会有底部的导航小圆点或者图片标题等元素,用于指示和切换不同的图片。当用户点击这些导航元素时,除了切换图片显示,还希望图片所在的轮播区域能自动滚动到可视范围,让用户清晰看到当前选中的图片。
示例代码
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
.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;
}