JavaScriptJavaScript·

JS高级使用3.0——JS中获取页面的高度、距离顶部的距离

投稿時間:2024-08-28 00:15:22閲覧数:38
専門記事
転載は出所を明記してください

创作场景

   记录闭包的博客中有一个节流函数的实际用法和这个知识点相关,创作过程中发现这个知识点涉及到的还有很多,在此记录一下相关的所有知识点并进行比较。

阅读前提

   此博客适用于所有人群,不仅有基础的用法,同时也对多种实现方式进行比较,本文将围绕一个例子进行讲解,并对涉及到的所有知识点进行穿插,最后进行总结。

提前了解的知识点

1. 页面可视化高度(clientHeight)

   页面可视化高度指的是你当前页面能看到内容的高度,这个高度是可以动态变化的,比如你打开了F12调试器,那么你的可视化高度就会变化,如果你将浏览器最大化,那么你的可视化高度也会变化,但这并不代表你实际页面的高度,可能你的页面高度会远远超过页面可视化高度。代码实现:

document.body.clientHeight

2. 滚动条高度(scrollHeight)

   滚动条高度就是当你的页面高度超过了页面可视化高度,比如body的高度是900,你的页面高度是800,那么滚动条就会产生,一般来说,滚动条高度是比你的页面高度要大16px,可能不同设备会不一样。代码实现:

document.body.scrollHeight

统计距离页面顶部的距离

参考:https://blog.csdn.net/mouday/article/details/125444003

  // 滚动方向枚举值
  const DIRECTION_ENUM = {
    DOWN: "down",
    UP: "up",
  };

   // 距离顶部或底部的阈值,一般滚动条高度是要比页面高度大的,阈值指的就是大的这一点儿
  const threshold = 20;
  // 记录前一个滚动位置
  let beforeScrollTop = 0;
  function handleScroll() {
    // 距顶部
    var scrollTop =
            document.documentElement.scrollTop || document.body.scrollTop 
            || window.pageYOffset || window.scrollY;
    // 可视区高度
    var clientHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
    // 滚动条总高度
    var scrollHeight =
            document.documentElement.scrollHeight || document.body.scrollHeight;

    // 打印数值,console.table是控制台打印表格的写法,同时也有
    // console.error和console.warn,对应警告和错误
    // 一般使用的就是console.info
    console.table([
      {
        label: "距顶部",
        value: scrollTop,
      },
      {
        label: "可视区高度",
        value: clientHeight,
      },
      {
        label: "滚动条总高度",
        value: scrollHeight,
      },
      {
        label: "距顶部 + 可视区高度",
        value: scrollTop + clientHeight,
      },
    ]);

    // 确定滚动方向
    let direction = DIRECTION_ENUM.DOWN;
    if (beforeScrollTop > scrollTop) {
      direction = DIRECTION_ENUM.UP;
    }

    // 通过滚动方向判断是触底还是触顶
    if (direction == DIRECTION_ENUM.DOWN) {
      // 滚动触底
      if (scrollTop + clientHeight + threshold >= scrollHeight) {
        console.log("滚动触底");
      }
    } else {
      // 滚动到顶部
      if (scrollTop <= threshold) {
        console.log("滚动到顶部");
      }
    }

    beforeScrollTop = scrollTop;
  }
  window.addEventListener('scroll', handleScroll)

window、document、documentElement的区别

window是当前页面的顶级对象,其中包含了很多属性和方法,是一个BOM对象,可进行浏览器的交互。
document是window对象的子元素,它可以理解为一个DOM对象,其中有很多方法和属性,主要是在页面元素中进行交互。

documentElement是document的子元素,注意,这是一个只读对象,也就是说它只能读取元素的属性,不能对元素进行操作。一般他就是你本页面的HTML元素。

这里一定要注意一下,如果你的页面是在一个iframe中,那你获取的一定是你iframe中的所有元素,并不是你最大页面的对象。一般在实际开发中都有头部导航栏,而子页面中也会嵌套子页面,那么获取最外部的HTML元素可以用parent对象,一层一层循环,因为最外部的iframe肯定是有一个ID的,这是我在开发中遇到的一个小问题,分享一下。

// 第一个参数是当前的iframe对象,第二个是parent对象
// 调用时parentNode不用传入
function getFrameTop(frame, parentNode) {
	if (frame.attr('id') !== "iframeContent") {
		if (parentNode) {
			frame = parentNode.parent.$("iframe")
		} else {
			frame = parent.$("iframe")
		}
		getFrameTop(frame, parent)
	} else {
		topIframe = frame
		return frame
	}
}

解读获取距离页面顶部距离的四种方式

    // 距顶部
    var scrollTop =
            document.documentElement.scrollTop || document.body.scrollTop 
            || window.pageYOffset || window.scrollY;

  这四种拆分下来就是在两个对象上进行操作的,一个是window,一个是document,而之所以这么写完全是为了兼容性,尤其是pageYOffset方法,这是一个过时方法,但是在某些IE就只能识别这个,如果你的产品不需要兼容,那其中一个就够用了。

   解读一下原理:

   我的div高度是900,页面可视化高度是818,而距离顶部的距离(scrollTop)是98,这其实就是滚动条的高度减去可视区高度算出来的,而这个高度指的是你的div最顶部距离和你可视化页面的顶部距离,如果是计算底部的距离,那加上页面可视化距离即可。

如何使用代码滚动页面(四种方式)

1. scroll()方法

滚动窗口至文档中的特定位置。
window.scroll(x, y) x和y就是你需要滚动的绝对位置坐标
window.scroll(options) options是一个对象,包含x、y坐标,同时也有滚动的方式
window.scroll({
  top: 100,
  left: 100,
  behavior: "smooth",
});

   上面这是一种标准用法,当然一般我们不这么写,直接用第一种方式滚动即可。

2. scrollBy()方法

在窗口中按指定的偏移量滚动文档(比如你只是想在这个基础上向下滚动100px)
scrollBy(x-coord, y-coord)
scrollBy(options)
x-coord 是你想滚动的水平像素值。
y-coord 是你想滚动的垂直像素值。
options
   包含以下参数的字典
top
   指定沿 Y 轴滚动窗口或元素的像素数。
left
   指定沿 X 轴滚动窗口或元素的像素数。
behavior
   指定滚动是否应该平滑(smooth)、瞬时运动到该位置(instant)、或者让浏览器选择(auto,默认)。
window.scrollBy({
  top: 100,
  left: 100,
  behavior: "smooth",
});

   这个方法和scroll区别在于,这里的x和y指的是偏移量,而不是绝对位置

3. scrollTo()

   这个和scroll方法是一样的,个人比较喜欢这种方式,因为可读性比较高,不容易出错,使用标准写法可以随意在x和y上进行随意滚动,因为对象上参数可选。

// 设置滚动行为改为平滑的滚动
window.scrollTo({
    top: 1000,
    behavior: "smooth"
});

4. document.documentElement.scrollTop = 0(非标准写法)

   上面说过documentElement是一个只读属性,官方上也是这么说的,但是经过实验发现这种方式也可以用来操作页面的滚动,但不建议这么使用,也不知道会存在什么bug。

使用节流函数优化

关于节流函数是什么,这个博客中有说明

节流函数(闭包中的使用)
  function throttle(func, wait){
    let previous = 0;
    return function() {
      var now = Date.now()
      var context = this
      // ES5写法:var args = []; args.push.apply(null, arguments)
      var args = [...arguments]	// ES6数组解构知识点:复制数组
      // 如果当前时间减去上一次执行时间大于我们执行函数的时间间隔再执行
      if(now - previous > wait){
        func.apply(context, args);
        // 闭包,记录本次执行时间戳
        // 这么写就是不用将上次执行的时间作为参数传给函数了
        // 就算多次调用闭包不会消失,上一次执行时间不会消失,这就是闭包的常用方式
        previous = now;
      }
    }
  }
  // 滚动方向枚举值
  const DIRECTION_ENUM = {
    DOWN: "down",
    UP: "up",
  };

  // 距离顶部或底部的阈值,一般滚动条高度是要比页面高度大的,阈值指的就是大的这一点儿
  const threshold = 20;
  // 记录前一个滚动位置
  let beforeScrollTop = 0;
  function handleScroll() {
    // 距顶部
    var scrollTop =
            document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset || window.scrollY;
    // 可视区高度
    var clientHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
    // 滚动条总高度
    var scrollHeight =
            document.documentElement.scrollHeight || document.body.scrollHeight;
    // 打印数值
    console.table([
      {
        label: "距顶部",
        value: scrollTop,
      },
      {
        label: "可视区高度",
        value: clientHeight,
      },
      {
        label: "滚动条总高度",
        value: scrollHeight,
      },
      {
        label: "距顶部 + 可视区高度",
        value: scrollTop + clientHeight,
      },
    ]);

    // 确定滚动方向
    let direction = DIRECTION_ENUM.DOWN;
    if (beforeScrollTop > scrollTop) {
      direction = DIRECTION_ENUM.UP;
    }

    // 通过滚动方向判断是触底还是触顶
    if (direction == DIRECTION_ENUM.DOWN) {
      // 滚动触底
      if (scrollTop + clientHeight + threshold >= scrollHeight) {
        console.log("滚动触底");
      }
    } else {
      // 滚动到顶部
      if (scrollTop <= threshold) {
        console.log("滚动到顶部");
      }
    }

    beforeScrollTop = scrollTop;
  }
  // window.addEventListener('scroll', handleScroll)
  window.addEventListener('scroll', throttle(handleScroll, 200))

这里只是一个例子,请注意,如果想要绝对精度,也就是当滚动条快速滑动的时候也要监听到,那就将延迟设置为0-50内。

总结

获取距离顶部的距离

  • document.documentElement.scrollTop
  • document.body.scrollTop
  • window.pageYOffset
  • window.scrollY

可视区高度

  • document.documentElement.clientHeight
  • document.body.clientHeight

滚动条总高度

  • document.documentElement.scrollHeight
  • document.body.scrollHeight

滚动页面

  • scroll()
  • scrollTo()
  • scrollBy()
  • document.documentElement.scrollY = 100


原文链接:https://blog.csdn.net/weixin_48588897/article/details/138413621

コメント欄

まだコメントがありません。最初のコメントを投稿しましょう!

弦圈热门内容

Vue.js与Nuxt.js的区别

Vue.js与Nuxt.js都是前端的两个框架,Vue.js的项目属于单页应用,而Nuxt.js是基于Vue.js的服务端渲染通用框架。单页应用简称SPA,指的是前端代码将会在浏览器端被浏览器渲染。这对SEO优化不利,搜索引擎爬虫,会爬到空的网页。在Vue项目中,Vue会将JS交给浏览器渲染因此,结果是查看源代码没有别的东西,搜索引擎爬虫也基本只能看到这些,于是便直接下一个了,不会等你渲染。而服务端渲染,简称SSR,正是该问题的解决方案。前端代码会先在Node.js服务端渲染,然后再交给浏览器进行“二次渲染”。Nuxt.js则是Vue.js的SSR通用解决方案。前端代码经过服务端渲染后,能让搜索引擎爬虫看到完整的网站,同时查看源代码也能看到完整的代码。服务端渲染能提高网站渲染速度,降低白屏时间。同时,因为要同时运行Node.js服务端,这增加了服务器的负载。在Nuxt.js中,可以设置部分页面SSR,部分页面则是SPA,这样能降低服务器的资源耗费。对于静态网站,可以使用预渲染替代服务端渲染。预渲染,简称SSG,指提前渲染静态的html,提高页面响应。SSG一般适用于文档、个人博客等场景 ...

Linux是什么?Linux简介

1. Linux操作系统这个词严格来说是不对的,因为Linux其实只是个宏内核,Linux的各个发行版才算得上是真正的操作系统。相比于Windows和unix,Linux是免费开源的(虽然某些发行版是付费的),其实Linux就诞生于这样的背景下。Linus还是学生的时候,他的一个老师因为不想用付费的unix教学,因此自己写了一个操作系统,免费开源。而Linus根据这个操作系统,自行开发出Linux系统。值得一提的是,手机安卓系统用的是Linux内核,而苹果系统用的则是unix系统的一个分支。在电脑的操作系统中,目前市场占比最高的仍然是Windows系统,Windows的图形界面相较于Linux的重命令行对于用户更友善,更易使用。而在服务器的操作系统中,很多服务器都使用Linux系统,因为Linux占的内存更小,相较于Windows更轻,服务器跑久了也不容易卡。同时,服务器基本上都是纯命令行的,因为安装桌面占用空间,因此使用纯命令行的Linux更合适,据说当初Linus就是不喜欢图形界面的。其实Linux也是可以安装图形环境的(即桌面),如GNOME、Xfce,但是有些云服务器,比如我现 ...

cover

如果假设地心人存在,就能解释为什么至今没有发现外星人

说到地心人这类阴谋论(斯诺登揭秘:地下世界真相,地心人真的存在吗?),原本应该当乐子看看就算了。但是如果假设地心人存在,并且是比地表人更高程度的文明,那么就能得出一些有趣的结论,能够解释以下几个问题。为什么至今没有发现外星人👽?为什么人类一直向外太空发射信息,向外星人问好,却没有回应?为什么不怕黑森林法则?​说到底还是因为人类太弱小了,人类科技发展到如今的程度,对整个地球的探索都只限于薄薄的表面。人类对地下最深处的探索记录,于整个地球而言,只相当于在一个蛋壳表面划掉一层皮。毕竟连最外面的地幔都只是钻了个小口。我们对于地底结构的认识很大程度上依赖于地震波。在这里我们展开想象,既然地心人假设存在,且拥有高度发达的文明,那么应该有相应的手段在地底完全隐匿起来,不被外面的人发现,且不会被地震波所暴露,甚至想在地底藏匿,避免地震波的影响本来就是一个前提条件。​上面论述中有个关键词是隐匿、藏匿,为什么地心人要藏起来呢?答案很简单,因为黑森林法则。有句话叫做闷声发大财,如果一个人刚刚发展起来,那么他一定会尽量低调,不被厉害的人盯上,保全自己。同样,一个文明刚刚发展起来,到了一个相对可观的程度(比如超 ...

cover

世界婴儿危机,我们要被婴儿淹没了吗?

在遥远的未来,一场前所未有的婴儿危机席卷全球,仿佛人类即将被这些无辜的小生命淹没。而这场危机的源头,竟然源自一个被誉为“世界第一X大国”的泡菜国。泡菜国因“伟哥河”的奇特现象,人口暴增,幼儿园爆满,无数孩子提前继承了家产。樱花国因难民涌入,出生率飙升,政府欢呼经济新曙光,半场开香槟。然而,樱花国很快因人口爆炸而面临前所未有的社会压力。驻樱花米军被迫撤离,并“意外”留下氢弹发生爆炸,人们以为能暂时缓解这场危机,但出乎所有人意料的是,这些新生儿们似乎拥有了对核辐射的免疫力。他们组成了一支支无意识的婴儿大军,跨越海洋,向世界各地迁徙。鹰酱国成为了他们新的目标,面对这些无辜又强大的生命,人们陷入了恐慌和混乱。

cover

宇宙真的是被造物主设计出来的吗?如果是,那么造物主是怎么样的存在?

我们所生活的宇宙是一个运转极其严密而又无比神秘的空间,时间,物质构造的综合体。每当我思考宇宙时,总有一个疑问随之而来,也挥之不去,这个疑问就是;我们的宇宙如此运行严密,如此奇巧,这到底是怎么形成的?难道宇宙的背后真的有造物主吗?难道宇宙真的是造物主设计出来的吗?图片来自网络在古老的人们对上天的崇拜和神话传说,到宗教文化,其都把宇宙的诞生归结于造物主的创造。当科学从最初的研究造物主存在的可能性,发展至当下科学形成一整套逻辑严密的学科,造物主似乎依然没有漏出其真实面容。图片来自网络对于宇宙是否是造物主所为,这个疑问始终伴随着我,只要我一思考宇宙的终极问题时,这个疑问总是第一时间跳出来,而我却无法回避,于是我抛开其它问题,死磕这个问题。终于在我付出了近4000个日夜的思考,终于对这个问题有了属于我自己的答案。图片来自网络我认为,所谓的造物主,其真实身份应该是宇宙运行法则,而宇宙运行法则是由宇宙最原始的构成条件,在其构成条件各自所存在的自性之间的相互作用而形成的自然反应所形成的。因此我认为我们宇宙的造物主就是;宇宙的构成材料和宇宙的运行法则。宇宙运行法则就是宇宙的造物主,他存在在宇宙之中的每个 ...