JavaScriptJavaScript·

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

Publié à 2024-08-28 00:15:22Vu 36 fois
Article professionnel
Réimpression Veuillez indiquer la source

创作场景

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

阅读前提

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

提前了解的知识点

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

Section des commentaires

Pas encore de commentaire, ajoutez le premier.

弦圈热门内容

cover

原创文章被检测为AI创作,AI检测还靠谱吗?

自从GPT火了以后,网络上的AI内容就变得泛滥了,刚开始还能轻松辨别哪些是AI的(一眼AI),哪些是人写的。现在这一两年里,随着生成式AI不断深入人心,AI内容变得更加泛滥了,并且经过这段时间技术的发展,AI生成的内容越来越真假难辨😢😤,有些AI生成的内容需要仔细辨别才能看出端倪。更可怕的是,道高一尺魔高一丈😔🙁,所谓的AI检测技术发展远远比不上AI生成技术的发展。AI生成的内容跟人越来越像,甚至有时候比人写的还要好,而人写的内容呢,相对的也就越来越AI化了😅。因此目前的AI检测会出现把人写的认定为AI写的荒谬事情。这也就意味着潘多拉魔盒已经彻底打开,AI内容与人的内容的界限开始变得模糊,所有的内容都变得真假难辨,恐怕这样下去人会彻底活在虚幻的世界里😭。以下为AI检测的结果我们检测用的是为什么说外国教材好?国外教材与国内教材的区别与 Djano云服务器部署 uwsgi+nginx+https部署这两篇文章。使用GPTZero进行检测,其他检测工具就不列举说明了,感觉用哪个AI检测结果都不会有太大差别。其实是别的AI检测都太不靠谱了😄,Undetectable.ai感觉就无论给它什么结果 ...

[antd: Message] You are calling notice in render which will break in React 18 concurrent mode. Please trigger in effect instead.

I'm getting this error when using MessageWarning: [antd: Message] You are calling notice in render which will break in React 18 concurrent mode. Please trigger in effect instead.Here is my code:import { message } from 'antd'; export default function Page() { const [messageApi, contextHolder] = message.useMessage(); const res = await fetch("/api/...", { method: "POST", }); if (!res.ok) { messageApi.error("Error! Fail to login!"); } return ( &lt;Home&gt; ... &lt;/Home&gt; ) }

逻辑回归算法介绍

逻辑回归是一种用于二分类和多分类任务的机器学习算法。尽管名字中包含“回归”一词,但它主要用于分类,而不是预测连续值。逻辑回归通过构建一个线性模型,并通过非线性函数将其映射到一个概率空间,从而实现分类。以下是逻辑回归的主要特点和工作原理:线性模型:逻辑回归首先构建一个线性模型。设 (x_1, x_2, \ldots, x_n) 是输入特征,(w_1, w_2, \ldots, w_n) 是权重,(b) 是偏置,那么线性组合可以表示为: [ z = w_1 \cdot x_1 + w_2 \cdot x_2 + \ldots + w_n \cdot x_n + b. ]Sigmoid函数:为了将线性模型的输出转换为概率,逻辑回归使用sigmoid函数,也称为逻辑斯蒂函数。该函数可以将任意实数映射到0和1之间,定义如下: [ \sigma(z) = \frac{1}{1 + \exp(-z)}. ]输出概率:通过sigmoid函数,线性模型的输出被转化为概率。对于二分类任务,这个概率可以解释为样本属于某个类别的概率。例如,如果我们预测输出为1的概率是0.7,那么预测输出为0的概率就是0.3。 ...

cover

浅谈《天国:拯救》中的骰子游戏

原链接: https://zhuanlan.zhihu.com/p/386924079?utm_campaign=shareopn&amp;utm_medium=social&amp;utm_psn=1806094671581167616&amp;utm_source=wechat_session 正文:《天国:拯救》是由战马工作室制作的中世纪RPG游戏,根据1403年发生的真实历史改编。本作的故事发生在中世纪时,匈牙利之王与瓦茨拉夫四世内战的波西米亚,《天国:拯救》的故事是根据真实历史改编的。随着贤君查理四世驾崩,神圣罗马帝国陷入了战争、腐败与混乱。瓦次拉夫,查理四世的儿子,却沉迷荒淫之事而不理朝政。瓦茨拉夫不满的宗亲贵族最后只能求助于瓦茨拉夫的皇兄——匈牙利之王,西格斯蒙德。但西格斯蒙德最后采用了极端的方式,绑架国王,逼其退位,趁乱夺权,其率部队大举进攻波西米亚,并侵蚀国王盟友的领地。在这乱世中,铁匠之子亨利在城镇斯卡里茨和父母过着平凡而快乐的生活,但这平静生活被一群库曼人雇佣军所打乱,他们收到了西格斯蒙德的亲令,掠夺并烧毁了城镇,在这次混乱中,亨利是为数不多的逃过这场浩劫的幸存者 ...

宇宙的最终结局会是什么?宇宙命运结局的三种假说

宇宙是如何诞生的?这个问题一直吸引着人类的好奇心。随着二十世纪六十年代,宇宙微波背景辐射的发现,科学界普遍认为,宇宙起源于大约138亿年前的一次大爆炸。然而,宇宙的最终结局又是怎样的呢?这是另一个让人类深思的问题。自人类诞生以来,人们就对死亡充满了恐惧,因为死亡意味着失去一切,无论是美好的事物,还是别的东西,全都将趋于“虚无”。虽然人类对死亡非常恐惧和厌恶,但是它似乎是宇宙中的一道铁律,目前仍然没有破解和逃脱的方法。不仅地球上所有的生物都难逃灭亡的结局,就连宇宙本身或许也不是永恒存在的,它也许会在遥远未来的某天迎来自己的终结,这已成为科学界公认的事实。关于宇宙的最终结局,科学家们提出了多种假说。其中一个是“大撕裂”理论,随着科学的发展,科学家们又提出了另外两种关于宇宙最终命运的假说:热寂和大坍缩。本期内容我们就来聊聊这个话题。1. 大撕裂假说图片来自网络宇宙的命运一直是天文学家争论不休的话题。有些人认为宇宙将永远存在,而另一些人则认为它最终会走向毁灭。如果你是一个科学家,你可能会对宇宙的未来感到担忧。因为有一种假说告诉我们,宇宙的结局可能是一场灾难性的大撕裂!大撕裂理论认为,宇宙的膨胀 ...

物理学家打造史上最难迷宫:极易碎成微粒

代达罗斯本可以从英国和瑞士的物理学家团队那里获取灵感。他们从分形几何和国际象棋的策略游戏中汲取原理,创造出了他们所说的有史以来最难的迷宫。在英国布里斯托尔大学物理学家菲利克斯·弗利克的带领下,这个研究小组在阿曼-比克尔平纹图案中产生了被称为汉密尔顿循环的路线,创造了复杂的分形迷宫。他们说,这些分形迷宫描述了一种被称为准晶体的特殊物质形态。它的灵感来自于一个骑士在棋盘上的移动。“当我们观察我们构建的线条的形状时,我们注意到它们形成了令人难以置信的复杂迷宫。随后迷宫的大小呈指数级增长,且数量无限,”弗莱克解释说。“在骑士之旅中,棋子(向前跳两个格,向右跳一个格)在回到起始方格前只访问一次棋盘的每个方格。这是‘汉密尔顿循环’的一个例子,即通过地图的循环只访问所有站点各一次。”准晶体是自然界中极其罕见的物质形态,是固体中有序和无序晶体的奇特混合。在有序的晶体中 —— 如盐、钻石或石英 —— 原子以非常整齐的模式排列,并在三维空间中重复。你可以将这个晶格的一部分叠加到另一部分上,它们就会完美地匹配。无序的或无定形的固体是指其中的原子都是乱糟糟的,包括玻璃和一些通常在地球上找不到的冰。准晶体是一种 ...

cover

为什么说外国教材好?国外教材与国内教材的区别

首先,不是所有国外的教材都是好的,也不是所有国内的教材写得不好。但整体上看,绝大多数的国外大学教材,要比国内的要好,而国内的教材好的屈指可数。国内的有些教材往往写得更加冗长和复杂,让人看得云里雾里、似懂非懂。而且封面简陋,排版一般,给学生的体验不太好,编者可能心里并没有将学生放在平等的位置上。这里就不具体列举国内哪些教材不好了😅😅😅。。国外的教材,往往有精美的封面,内容写得清晰明了,有舒服整齐的排版,有的时候会配上精美的图片或图案。国外的教材给人的感觉是大制作,把学生放在重要的位置,阅读体验非常好。有些比较基础的教材,比如说微积分,看教材能感觉到作者想方设法让你能学懂,巴不得背你上去。老师的本职应该是服务学生,如果没有学生来上学,那么学校也没有开的必要了,老师也会丢掉工作。因此,国内外的教育环境差别,通过教材也能撇到冰山一角。以下以国外的《大学物理》教材为例:精美的封面舒适的排版精美的图案清晰详细的内容可见,如果我们上课的时候,能够用上这样的教材,也不至于这么苦逼来啃教材,而是享受阅读。然而,国外的教材大制作,价格往往比国内的教材要贵得多,一本教材换成人民币可能要几百块。但国外的网上教 ...