七爪源码:纯 CSS 和 JS 的原生平滑滚动
zhezhongyun 2024-12-26 17:42 59 浏览
纯 CSS 和 JS 的原生平滑滚动
你想要一个平滑的滚动吗? 忘记 JQuery,我们已经过去了。 让我向您介绍我们的原生平滑滚动工具。
CSS 滚动行为
CSS scroll-behavior 属性接受三个值之一 - 实际上是两个值,因为其中一个已被弃用。
- scroll-behavior: auto 是我们已经习惯的默认即时滚动行为。
- scroll-behavior:instant 与 auto 相同,这就是它被弃用的原因。 如果你想要它,只需使用自动。
- scroll-behavior: smooth 在以编程方式触发滚动事件时应用平滑过渡。
我说“以编程方式触发”是因为它不会平滑滚动鼠标滚轮。
以编程方式触发滚动事件的一些方法是:
- Window.scrollTo()
- Window.scrollBy()
- Element.scrollTo()
- Element.scrollBy()
- Element.scrollIntoView()
- Element.scrollLeft = x
- Element.scrollTop = y
我们将分别探索这些方法。
(注)Window.scroll() 和 Element.scroll()
也许你已经注意到我没有提到 scroll() 方法。
这是因为 Window.scroll() 和 Element.scroll() 实际上是与 Window.scrollTo() 和 Element.scrollTo() 相同的方法。为避免重复内容,我将仅参考 scrollTo()。在实践中,您可以使用任何一种,只需选择一个并保持一致。
Window.scrollTo() 和 Element.scrollTo()
此方法非常适合滚动到绝对坐标。如果您有要将用户滚动到的位置的 x 和 y 坐标,您可以简单地调用 window.scrollTo(x, y) ,它会尊重页面的 CSS 滚动行为。
这同样适用于可滚动元素。您只需调用 element.scrollTo(x, y) ,它就会尊重元素的 CSS 滚动行为。
这个方法还有一个新的签名,它使用一个对象而不是两个数字参数,通过这个新的签名,我们可以显式地设置我们的滚动行为。
// For window
window.scrollTo({
left: x,
top: y,
behavior: 'smooth'
});
// For element
const el = document.querySelector(...);
el.scrollTo({
left: x,
top: y,
behavior: 'smooth'
});
Element.scrollLeft 和 Element.scrollTop
设置元素 .scrollLeft 和 .scrollTop 属性与使用坐标调用 Element.scrollTo() 相同。 它将尊重元素的 CSS 滚动行为。
const el = document.querySelector(...);
const x = 100;
const y = 500;
// Setting .scrollLeft and .scrollTop with smooth scroll
el.style.scrollBehavior = 'smooth';
el.scrollLeft = x;
el.scrollTop = y;
// Is the same as calling Element.scrollTo()
el.scrollTo({ left: x, top: y, behavior: 'smooth' });
(注)负元素.scrollLeft
如果你的元素文本的方向是 rtl,scrollLeft = 0 表示水平滚动的最右边位置,并且随着你向左移动,值会减小。
对于宽度为 100px,可滚动宽度为 500px,方向为 rtl 的可滚动元素,最左边的位置是 scrollLeft = -400。
<div id="scrollable" style="width: 100px; overflow: auto" dir="rtl">
<div style="width: 500px; height: 100px; background: green"></div>
</div>
<p id="output"></p>
const scrollable = document.querySelector('#scrollable');
const output = document.querySelector('#output');
const updateOutput = () => {
output.textContent = `scrollLeft: ${scrollable.scrollLeft}`;
};
updateOutput();
scrollable.addEventListener('scroll', updateOutput);
Window.scrollBy() 和 Element.scrollBy()
此方法与 Window.scrollTo() 或 Element.scrollTo() 具有完全相同的签名。 它接受 x 和 y 作为两个数字参数或作为具有可选 left、top 和 behavior 属性的对象的单个参数。
这里的区别是我们不是传递绝对坐标,而是相对值。 如果我们 scrollBy({ top: 10 }),我们从当前位置向下滚动 10 个像素,而不是从页面开头向下滚动 10 个像素。
// For window
window.scrollBy({ top: 10 }); // Scroll 10px down
window.scrollBy({ left: 20 }); // Then 20px to the right
window.scrollBy({ top: 50 }); // And then 50px down
// For element
const el = document.querySelector(...);
el.scrollBy({ top: 10 }); // Scroll 10px down
el.scrollBy({ left: 20 }); // Then 20px to the right
el.scrollBy({ top: 50 }); // And then 50px down
(注) Window.scrollByLines() 和 Window.scrollByPages()
Firefox 更进一步,实现了滚动多行或多页的方法。 这是一个仅适用于 Firefox 的非标准功能,因此您可能不想在生产中使用它。
通过将 100vh(用于页面)和 1rem(用于行)转换为像素并将该值传递给 Window.scrollBy(),您可以在所有主要浏览器中实现类似的效果。
const toPixels = require('to-px'); // From NPM
const page = toPixels('100vh');
window.scrollBy(0, page); // window.scrolByPages(1)
const line = toPixels('1rem');
window.scrollBy(0, line); // window.scrolByLines(1)
Element.scrollIntoView()
但大多数时候,我们并不关心任何硬编码的坐标,我们只想将用户滚动到屏幕上的特定元素。 这可以通过 Element.scrollIntoView() 轻松(更明确地)完成。
可以不带参数调用此方法,它将滚动页面(尊重 CSS 滚动行为)直到元素在顶部对齐(除非元素在页面底部,在这种情况下,它会 尽可能滚动)。
<div style="height: 2000px">Some space</div>
<div id="target" style="background: green">Our element</div>
<div style="height: 500px">More space</div>
const target = document.querySelector('#target');
target.scrollIntoView();
您可以通过传递布尔值或对象来进一步自定义元素在视图中的位置。
const el = document.querySelector(...);
// Default, aligns at the top
el.scrollIntoView(true);
// Aligns at the bottom
el.scrollIntoView(false);
// Aligns vertically at the center
el.scrollIntoView({ block: 'center' });
// Vertical top and horizontal center
el.scrollIntoView({ block: 'start', inline: 'center' });
// Vertical bottom and horizontal right
el.scrollIntoView({ block: 'end', inline: 'end' });
// Vertical center and smooth
el.scrollIntoView({ block: 'center', behavior: 'smooth' });
// Vertical nearest
el.scrollIntoView({ block: 'nearest' });
当使用一个对象来定义元素的位置时,注意 block 是指垂直放置,而 inline 是指水平放置。此外,“最近”的位置可以是顶部/左侧或底部/右侧,以最近的为准,如果元素已经在视图中,它也可以是空的。
浏览器支持
{关于浏览器支持} 在撰写本文时,所有主流浏览器(Safari 除外)都支持平滑滚动和本文中描述的滚动方法。
如果你需要更多的保证,我在我的项目中使用了一个非常好的平滑滚动 polyfill。它填充了 scroll()、scrollTo()、scrollBy()、scrollIntoView() 和 CSS 滚动行为。它不支持通过设置 scrollLeft/scrollTop 来平滑滚动,也不支持 scrollIntoView() 选项(它总是在顶部对齐元素)。
如果你有更多的好奇心,我强烈建议你研究一下 polyfill 的源代码,总共不到 500 行。我做了一个 PR 来稍微改进文档,你可能会发现代码更容易理解。
祝你有美好的一天,很快见到你。
相关推荐
- perl基础——循环控制_principle循环
-
在编程中,我们往往需要进行不同情况的判断,选择,重复操作。这些时候我们需要对简单语句来添加循环控制变量或者命令。if/unless我们需要在满足特定条件下再执行的语句,可以通过if/unle...
- CHAPTER 2 The Antechamber of M de Treville 第二章 特雷维尔先生的前厅
-
CHAPTER1TheThreePresentsofD'ArtagnantheElderCHAPTER2TheAntechamber...
- CHAPTER 5 The King'S Musketeers and the Cardinal'S Guards 第五章 国王的火枪手和红衣主教的卫士
-
CHAPTER3TheAudienceCHAPTER5TheKing'SMusketeersandtheCardinal'SGuard...
- CHAPTER 3 The Audience 第三章 接见
-
CHAPTER3TheAudienceCHAPTER3TheAudience第三章接见M.DeTrévillewasatt...
- 别搞印象流!数据说明谁才是外线防守第一人!
-
来源:Reddit译者:@assholeeric编辑:伯伦WhoarethebestperimeterdefendersintheNBA?Here'sagraphofStea...
- V-Day commemorations prove anti-China claims hollow
-
People'sLiberationArmyhonorguardstakepartinthemilitaryparademarkingthe80thanniversary...
- EasyPoi使用_easypoi api
-
EasyPoi的主要特点:1.设计精巧,使用简单2.接口丰富,扩展简单3.默认值多,writelessdomore4.springmvc支持,web导出可以简单明了使用1.easypoi...
- 关于Oracle数据库12c 新特性总结_oracle数据库12514
-
概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...
- 【开发者成长】JAVA 线上故障排查完整套路!
-
线上故障主要会包括CPU、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题...
- 使用 Python 向多个地址发送电子邮件
-
在本文中,我们将演示如何使用Python编程语言向使用不同电子邮件地址的不同收件人发送电子邮件。具体来说,我们将向许多不同的人发送电子邮件。使用Python向多个地址发送电子邮件Python...
- 提高工作效率的--Linux常用命令,能够决解95%以上的问题
-
点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...
- linux常用系统命令_linux操作系统常用命令
-
系统信息arch显示机器的处理器架构dmidecode-q显示硬件系统部件-(SMBIOS/DMI)hdparm-i/dev/hda罗列一个磁盘的架构特性hdparm-tT/dev/s...
- 小白入门必知必会-PostgreSQL-15.2源码编译安装
-
一PostgreSQL编译安装1.1下载源码包在PostgreSQL官方主页https://www.postgresql.org/ftp/source/下载区选择所需格式的源码包下载。cd/we...
- Linux操作系统之常用命令_linux系统常用命令详解
-
Linux操作系统一、常用命令1.系统(1)系统信息arch显示机器的处理器架构uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系...
- linux网络命名空间简介_linux 网络相关命令
-
此篇会以例子的方式介绍下linux网络命名空间。此例中会创建两个networknamespace:nsa、nsb,一个网桥bridge0,nsa、nsb中添加网络设备veth,网络设备间...
- 一周热门
- 最近发表
-
- perl基础——循环控制_principle循环
- CHAPTER 2 The Antechamber of M de Treville 第二章 特雷维尔先生的前厅
- CHAPTER 5 The King'S Musketeers and the Cardinal'S Guards 第五章 国王的火枪手和红衣主教的卫士
- CHAPTER 3 The Audience 第三章 接见
- 别搞印象流!数据说明谁才是外线防守第一人!
- V-Day commemorations prove anti-China claims hollow
- EasyPoi使用_easypoi api
- 关于Oracle数据库12c 新特性总结_oracle数据库12514
- 【开发者成长】JAVA 线上故障排查完整套路!
- 使用 Python 向多个地址发送电子邮件
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- opacity 属性 (32)
- transition 属性 (33)