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

embedded/2025/1/12 17:52:51/

文章目录

    • 一.基本概念
    • 二.语法和参数
      • 基本语法:`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类似的值,如startcenterendnearest,其含义和在垂直方向上类似,只是作用于水平方向。

三.应用场景和示例

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

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

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) => (<imgkey={image.id}id={`image-${index}`}src={image.src}alt={image.title}className="carousel-image"/>))}</div><div className="carousel-nav">{images.map((image, index) => (<spankey={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;
}

http://www.ppmy.cn/embedded/153347.html

相关文章

从零开始搭建一个RESTful API(Node.js + Express)

随着Web开发的普及&#xff0c;RESTful API已经成为开发者在后端开发中的常见方式。RESTful API通过标准的HTTP方法&#xff08;GET、POST、PUT、DELETE&#xff09;实现客户端和服务器之间的通信&#xff0c;使得前后端开发能够解耦&#xff0c;前端可以通过API获取数据并进行…

ip属地功能有什么作用?自己的ip属地哪里看

虽然现在各大平台纷纷推出了IP属地功能。但是很多小伙伴还是不太了解&#xff0c;为什么要开启这个功能&#xff0c;那么&#xff0c;IP属地功能究竟有哪些作用&#xff1f;又该如何查看自己的IP属地信息呢&#xff1f;本文将为您一一解答。 一、IP属地功能有什么作用 ‌IP属地…

element plus 使用 el-tree 组件设置默认选中和获取所有选中节点id

1. 设置默认选中&#xff1a; 使用 default-checked-keys 属性&#xff0c;设置默认要选中的节点&#xff0c;以数组形式&#xff0c;如下&#xff1a; <el-treeref"treeRef":data"data"show-checkboxnode-key"id":props"defaultProps…

【Python项目】基于深度学习的身份证识别考勤系统

【Python项目】基于深度学习的身份证识别考勤系统 技术简介&#xff1a;采用Python技术、MYSQL数据库等实现。 系统简介&#xff1a;首先会把总用户数、总打卡数、当前年份以及当前月份等等各种信息一一统计出来&#xff1b;新增用户就是通过训呼信息的方式输入&#xff0c;将用…

移动支付安全:五大威胁及防护策略

随着移动支付的普及和便利&#xff0c;越来越多的用户选择通过支付应用进行日常交易。根据艾利德市场研究公司&#xff08;Allied Market Research&#xff09;的报告&#xff0c;全球移动支付市场预计到2027年将超过12万亿美元。然而&#xff0c;随着市场的增长&#xff0c;移…

K8S集群更新api-sever证书的SAN属性

一、场景 1、当你的api-server需要更新API 服务器的地址和端口号就会使用到SAN属性证书。 2、查看证书的SAN属性 openssl x509 -in server.crt -text -noout | grep -A1 "Subject Alternative Name" *192.168.91.105是我更新的kube-vip进去,这样如果访问 192.168.9…

springboot + vue+elementUI图片上传流程

1.实现背景 前端上传一张图片&#xff0c;存到后端数据库&#xff0c;并将图片回显到页面上。上传组件使用现成的elementUI的el-upload。、 2.前端页面 <el-uploadclass"upload-demo"action"http://xxxx.xxx.xxx:9090/file/upload" :show-file-list&q…

Mysql连接报错排查解决记录

Mysql连接报错排查解决记录 背景&#xff1a; 系统&#xff1a;uos server-1060e​ 运行环境kvm虚拟机​ mysql版本&#xff1a;5.7.44, for Linux (x86_64)问题现象&#xff1a; 宿主机重启后&#xff0c;kvm虚拟机内的mysql服务无法远程连接了。通过不同的客户端工具连接…