Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >JS滑动滚动的n种方式

JS滑动滚动的n种方式

作者头像
源心锁
发布于 2022-08-12 03:38:11
发布于 2022-08-12 03:38:11
6.7K00
代码可运行
举报
文章被收录于专栏:前端魔法指南前端魔法指南
运行总次数:0
代码可运行

JS滑动滚动的n种方式

# 阅读本文,你将:

  1. 了解原生JS实现页面滚动的多种方式
  2. 了解这多种方式可以对应上的效果以及推荐的应用场景
  3. 多个滑动方面的坑以及相应(如果有)的解决方案
  4. 获得一些有用的函数

实现汇总

1 scrollIntoView

1.1 基本用法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let element = document.getElementById("scrollView");
 
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});

scrollIntoView对页面元素调用,会滚动元素的父容器,将该元素滚动到浏览器的可视区域

这是对hash锚点定位的进化升级,对于常用框架由于使用了hashRouter导致锚点定位失效的情况是一种不错的补偿

1.2 API介绍

alignToTop可选

一个Boolean值:

  • 如果为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐。相应的 scrollIntoViewOptions: {block: "start", inline: "nearest"}。这是这个参数的默认值。
  • 如果为false,元素的底端将和其所在滚动区的可视区域的底端对齐。相应的scrollIntoViewOptions: {block: "end", inline: "nearest"}

scrollIntoViewOptions 可选

一个包含下列属性的对象:

  • behavior 可选 定义动画过渡效果, "auto""smooth" 之一。默认为 "auto"
  • block 可选 定义垂直方向的对齐, "start", "center", "end", 或 "nearest"之一。默认为 "start"
  • inline 可选 定义水平方向的对齐, "start", "center", "end", 或 "nearest"之一。默认为 "nearest"
1.3 浏览器的支持度
1.4 示例与推荐使用场景
  • 原始位置图

我们定位如图红框的元素,从顶部开始示例

1.4.1 scrollIntoVIew()

页面滑动至父级容器,但是子项并没有被滑动到可视区域

1.4.2 scrollIntoView(false)

页面滑动到底部,该元素从下方进入可视区域

1.4.3 scrollIntoView({block:"center",inline:"center"})

仍然是没有看到我们要呈现的元素,疑似原因为我们的选定元素的爷爷级元素才是可滑动的

1.5 补充
  1. scrollIntoViewscrollIntoViewIfNeeded的区别在于,第一前者的支持性较高,后者则仍是非标准的。
  2. 功能上则是,后者如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。
  3. 有出现父容器滑动不到指定地方的问题,可以两次调用api(注意异步)

2 设置scrollTop/scrollLeft

2.1 基本用法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
element.scrollTop=100;

当我们获取到一个元素,直接设置它的scrollTop即可

2.2 scrollTop的坑,请仔细阅读

scrollTop是什么?为什么我们设置scrollTop总是无效。在使用scrollTop之前我们必须先了解scrollTop是什么。

根据MDN上的定义可知

Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。 一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0

那么,如果一个元素没有滚动条,采用的是transform模拟滚动,那么就无效咯

2.3 适用性检测

可以用下边的代码在控制台检测一下页面有没有任何一个地方的代码scrollTop不是0的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let elementList=[]
const elementBy=(start)=>{
    if(!start?.children || start?.children?.length===0){
        return null
    }
    for(let i=0;i<start.children.length;i++){
      	elementBy(start.children[i]);
    }
    if(start.scrollTop!=0){
        elementList.push(start)
    }

}
elementBy(document.body);
console.log(elementList);

能找到你希望的元素才适用scrollTop设置滑动条

2.4 使用示例

原位置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
elementList[0].scrollTop=100

可以看到明显的,符合预期的scrollview区域滑动

3 window.scrollToelement.scrollTo

3.1 基本用法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.scrollTo({
  left:0,
  top:0,
  behavior:'smooth'//或'auto'
}); //有效
window.scrollTo(0,0) //有效

上述两种参数形式都有效,作用是返回到顶部。

区别是设置behavior为'smooth'后会平滑滚动

3.2 使用说明

如果场景要求我们滚动页面到某个元素的位置,此时可以使用window.scrollTo();

如果场景要求我们滚动到某个可滚动父元素的位置,此时可以使用element.scrollTo();

相比较于上边的scrollIntoView,我们可以更自由的控制元素显示的位置

3.2 补充
  1. 设置横坐标无效的情况请确定下方出现了横向滚动条,即页面宽度需要大于浏览器宽度
  2. 常见误解:element.scrollTo并不是将某个元素滚动到页面某个位置,而是如果该元素可滚动,设置该元素的滚动条

4 window.scrollByelement.scrollBy

4.1 基本用法

啊哈,这个api一看就是element.scrollTo的近亲

实际功能体现上同样如此,该api用于相对滚动

对比window.scrollTo的话:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.scrollTo(x(),y());
//等同于
window.scrollLeft=x();
window.scrollTop=y();

//而scrollBy则:
window.scrollBy(10,20);
window.scrollLeft+=10;
window.scrollTop+=20;
4.2 其他

同上方的scrollTo

5 window.scrollelement.scroll

滚动相关的api还包含这位,不过经查,该api和scrollTo效果完全相同


接下来是没什么用系列滚动api

6 window.scrollByLines

该api仅FireFox支持

6.1 基本用法

表示相对当前的滚动位置再滚动指定行数距离,行为表现接近于上下键控制滚动

例如window.scrollByLines(-5)表示向上滚动5行

7 window.scrollByPages

该api仅FireFox支持

7.1 基本用法

表示相对当前的滚动位置再滚动指定页数距离,行为表现接近于空格键(反向+Shift)控制滚动

例如window.scrollByPages(-1)表示向上滚动1页的距离

扩展

1 找到页面内哪个元素的scrollTop不为0

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let elementList=[]
const elementBy=(start)=>{
    if(!start?.children || start?.children?.length===0){
        return null
    }
    for(let i=0;i<start.children.length;i++){
      	elementBy(start.children[i]);
    }
    if(start.scrollTop!=0){
        elementList.push(start)
    }

}
elementBy(document.documentElement);
console.log(elementList)

2 scrollByLines与scrollByPages的polyfill

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(function polyfillScroll(){
  if(!window.scrollByLines){
    window.scrollByLines=(lines)=>window.scrollBy(0,30*lines);
  }
  if(!window.scrollByPages){
    window.scrollByPages=(pages)=>window.scrollBy(0,document.body.clientHeight*pages);
  }
})()

3 元素宽高属性展示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const getHWInfo = () => ({
    "网页可见区域宽": `${document.body.clientWidth}`,
    "网页可见区域高": `${document.body.clientHeight}`,
    "网页可见区域宽(包括边线和滚动条的宽)": `${document.body.offsetWidth} `,
    "网页可见区域高 (包括边线的宽)": `${document.body.offsetHeight}`,
    "网页正文全文宽": `${document.body.scrollWidth}`,
    "网页正文全文高": `${document.body.scrollHeight}`,
    "网页被卷去的高(ff)": `${document.body.scrollTop}`,
    "网页被卷去的高(ie)": `${document.documentElement.scrollTop}`,
    "网页被卷去的左": `${document.body.scrollLeft}`,
    "网页正文部分上": `${window.screenTop}`,
    "网页正文部分左": `${window.screenLeft}`,
    "屏幕分辨率的高": `${window.screen.height}`,
    "屏幕分辨率的宽": `${window.screen.width}`,
    "屏幕可用工作区高度": `${window.screen.availHeight}`,
    "屏幕可用工作区宽度": `${window.screen.availWidth}`,
    "你的屏幕设置是": `${window.screen.colorDepth}位彩色`,
    "你的屏幕设置": `${window.screen.deviceXDPI} 像素/英寸`,
});
console.table(getHWInfo());

4 判断元素是否可以滚动

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function eleCanScroll(ele, direction = "y") {
    if (!(ele instanceof HTMLElement)) {
        console.error("eleCanScroll(ele:HTMLElement,direction:'y'|'x'| undefined)");
        return;
    }
    if (direction === "y"){
        if (ele.scrollTop > 0) {
            return true;
        } else {
            ele.scrollTop++;
            const top = ele.scrollTop;
            top && (ele.scrollTop = 0);
            return top > 0;
        } 
    } else if (direction === "x"){
        if (ele.scrollLeft > 0) {
            return true;
        } else {
            ele.scrollLeft++;
            const left = ele.scrollLeft;
            left && (ele.scrollLeft = 0);
            return left > 0;
        } 
    }
}

5 找到某元素外层第一个可滚动的元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const findScrollEle=(ele,direction="y")=>{
  if(!ele) return null;
  if(eleCanScroll(ele,direction)) return ele;
  return findScrollEle(ele.parentElement,direction);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
offsetWidth,clientWidth的区别
包括元素的宽度、可见的垂直滚动条宽度、左边框高度和右边框高度
全栈程序员站长
2022/09/16
7130
Selenium系列(22) - 通过selenium控制浏览器滚动条的几种方式
https://www.cnblogs.com/poloyy/category/1680176.html
小菠萝测试笔记
2020/06/09
1.3K0
说说几个 API 和应用案例
除了 classList.contains 方法之外,还有一个 node.contains 方法,这个方法返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点。语法:
多云转晴
2020/03/26
1.8K0
说说几个 API 和应用案例
[第19期] 介绍一个页面平滑滚动小技巧
今天写需求的时候发现一个小的优化点:用户选择了一些数据之后, 选择的条目需要高亮, 有时候列表很长, 为了提升用户体验,需要加个滚动, 自动滚动到目标位置。
皮小蛋
2020/02/29
1.4K0
Web前端实现锚点功能的三种方式
这种方式非常简单,给待跳转元素添加 id,之后修改 window.location 即可,用法如
lonelydawn
2022/09/01
3.8K0
【Python爬虫实战】全面掌握 Selenium 的 IFrame 切换、动作链操作与页面滚动技巧
在使用 Selenium 进行网页自动化测试或数据抓取时,我们经常会遇到需要操作 iframe、模拟复杂的 用户交互动作,以及处理 动态加载页面 的情况。这些操作是实现稳定且高效自动化流程的关键。本指南将详细介绍如何切换 iframe、使用动作链执行复杂交互,以及如何通过页面滚动加载更多内容。无论是自动化测试还是爬取动态网页,这些技巧都能帮助你更好地控制浏览器。
易辰君
2024/11/07
4670
JS 获取浏览器窗口大小clientWidth、offsetWidth、scrollWidth「建议收藏」
在我本地测试当中: 在IE、FireFox、Opera下都可以使用 document.body.clientWidth document.body.clientHeight 即可获得,很简单,很方便。 而在公司项目当中: Opera仍然使用 document.body.clientWidth document.body.clientHeight 可是IE和FireFox则使用 document.documentElement.clientWidth document.documentElement.clientHeight 原来是W3C的标准在作怪啊
全栈程序员站长
2022/09/16
7.5K0
JS 获取浏览器窗口大小clientWidth、offsetWidth、scrollWidth「建议收藏」
python自动化之JS处理滚动条
滚动条操作 浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript也就是JS来控制浏览器的滚动条。 WebDriver提供了execute_script()方法来执行JavaScript代码。 js="window.scrollTo(100,450);" driver.execute_script(js) 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。 这时候需要借助滚动条来拖动屏幕,使被操作的元素显示在当前的屏幕上。 滚动条是无法直接用定位工具来定位的。selenium里面也没有直接的方法去控制滚动条,这时候只能借助JS了,还好selenium提供了一个操作js的方法: execute_script(),可以直接执行js的脚本。 --scrollHeight 获取对象的滚动高度。 --scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离。 --scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离。 --scrollWidth 获取对象的滚动宽度。
Python研究者
2020/09/28
5.1K0
你也许不知道的浏览器的一些"滚动"行为
最近挺忙的,这次抽空写写文陶冶下情操,浏览器滚动真的天天见日日见啦,比如你现在看的这篇文章,往下看就必须得滚动,这篇文章主要聊聊滚动相关的一些方法跟属性,还有一些有趣的例子? 文章涉及到的方法或属性在
桃翁
2019/09/17
3.1K0
你也许不知道的浏览器的一些"滚动"行为
点击按钮,回到页面顶部的5种写法
2.scrollTop:scrollTop属性表示被隐藏在内容区域上方的像素数。元素未滚动时,scrollTop的值为0,如果元素被垂直滚动了,scrollTop的值大于0,且表示元素上方不可见内容的像素宽度
全栈程序员站长
2022/09/07
2.7K0
第52天:offset家族、scroll家族和client家族的区别
一、offset家族 1、offsetWidth offsetHeight offsetLeft offsetTop offsetParent共同组成了offset家族,用来获取元素尺寸。 offsetWidth = width + padding + border offsetHeight = height + padding + border 2、offsetLeft 和 offsetTop: 返回距离上级带有定位的盒子左边的位置,如果父级元素没有定位,则以body为准 offsetLeft从父亲的
半指温柔乐
2018/09/11
7860
第52天:offset家族、scroll家族和client家族的区别
元素滚动 scroll 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
星辰_大海
2020/09/30
1.3K0
js中scroll滚动相关
scrollBy(x,y)方法滚动当前window中显示的文档,x和y指定滚动的相对量。
小小咸鱼YwY
2020/06/19
7.9K0
忍法,scroll 翻滚之术!
但其实随着时间的推移, web api 以及 css 规范的不断改进,那些我们曾经认为实现起来很麻烦的功能也变得简单了起来。下面我们可以一起来探讨一下这些改进的内容。
陈大鱼头
2020/04/16
1.4K0
忍法,scroll 翻滚之术!
1.元素滚动 scroll 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
梨涡浅笑
2022/05/08
7810
1.元素滚动 scroll 系列
native 嵌套H5弹出虚拟键盘遮挡界面及其input 文本框上提及其置顶显示
      在于你的布局,可以用定位position:fixed;来做处理,因为他相对于页面来说,定位于屏幕一定的位置。
White feathe
2021/12/08
1.1K0
python自动化17-JS处理滚动条
    selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了。
py3study
2020/01/19
6.1K0
python自动化17-JS处理滚动条
操作滚动条小结:scrollIntoView/animate等方法的来龙去脉
操作滚动条可以通过锚点跳转,JS操作滚动条,与scrollIntoView等方法。对此,我来考古一下。
周陆军博客
2024/01/15
3970
vue里监听页面滚动的问题
网页可见区域宽: document.body.offsetWidth(包括边线的宽);
用户1065635
2019/03/21
3.4K0
js滚动到页面顶部
js平滑滚动到顶部,底部,指定地方 采用锚点进行页面中的跳转的确很方便,但是要想增加网页的效果,可以使用jquery中的animate,实现滚动的一个动作,慢慢的滚动到你想跳转到的位置 滚动到顶部:
IT工作者
2022/01/15
13.4K0
推荐阅读
相关推荐
offsetWidth,clientWidth的区别
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验