这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

Js中有一些比较冷门但是非常好用的方法,我在这里称之为高级方法,这些方法没有被广泛使用或多或少是因为存在一些兼容性的问题,不是所有的浏览器都读得懂的。这篇文章主要就是对这些方法做一个总结,有些方法在我们开发过程中有着重要的作用,我们一起来看一下吧。

getBoundingClientRect()

getBoundingClientRect() 是一个用于获取元素位置和尺寸信息的方法。它返回一个 DOMRect对象,其提供了元素的大小及其相对于视口的位置,其中包含了以下属性:

  • x:元素左边界相对于视口的 x 坐标。
  • y:元素上边界相对于视口的 y 坐标。
  • width:元素的宽度。
  • height:元素的高度。
  • top:元素上边界相对于视口顶部的距离。
  • right:元素右边界相对于视口左侧的距离。
  • bottom:元素下边界相对于视口顶部的距离。
  • left:元素左边界相对于视口左侧的距离。
  1. const box = document.getElementById('box');
  2. const rect = box.getBoundingClientRect();
  3.  
  4. console.log(rect.x); // 元素左边界相对于视口的 x 坐标
  5. console.log(rect.y); // 元素上边界相对于视口的 y 坐标
  6. console.log(rect.width); // 元素的宽度
  7. console.log(rect.height); // 元素的高度
  8. console.log(rect.top); // 元素上边界相对于视口顶部的距离
  9. console.log(rect.right); // 元素右边界相对于视口左侧的距离
  10. console.log(rect.bottom); // 元素下边界相对于视口顶部的距离
  11. console.log(rect.left); // 元素左边界相对于视口左侧的距离

为了更好地理解,我在页面上设置了一个容器,其对应属性看下图:

应用场景

这个方法通常用于需要获取元素在视口中的位置和尺寸信息的场景,比如实现拖拽、定位或响应式布局等,兼容性很好,一般用滚动事件比较多。

特殊场景会用上,比如你登录了淘宝的网页,当你下拉滑块的时候,下面的图片不会立即加载出来,有一个懒加载的效果。当上面一张图片没在可视区内时,就开始加载下面的图片。

下面代码就是判断一个容器是否出现在可视窗口内:

  1. const box = document.getElementById('box')
  2. window.onscroll = function () {//window.addEventListener('scroll',()=>{})
  3. console.log(checkInView(box));
  4. }
  5.  
  6. function checkInView(dom) {
  7. const { top, left, bottom, right } = dom.getBoundingClientRect();
  8. return top > 0 &&
  9. left > 0 &&
  10. bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  11. right <= (window.innerWidth ||
  12. document.documentElement.clientWidth)
  13. }

当容器在可视区域内就输出true,否则就是false

intersectionObserver

IntersectionObserver 是一个构造函数,可以接收两个参数,第一个参数是一个回调函数,第二个参数是一个对象。这个方法用于观察元素相交情况,它可以异步地监听一个或多个目标元素与其祖先元素或视口之间的交叉状态。它提供了一种有效的方法来检测元素是否可见或进入视口。

用法

使用 IntersectionObserver 需要以下步骤:

  1. 创建一个 IntersectionObserver 实例,传入一个回调函数和可选的配置对象。
  1. const observer = new IntersectionObserver(callback, options);
  2. const callback = (entries, observer) => {
  3. // 处理交叉状态变化的回调函数
  4. };
  5.  
  6. const options = {
  7. // 可选配置
  8. };
  1. 将要观察的目标元素添加到观察者中。
  1. const target = document.querySelector('#targetElement');
  2. observer.observe(target);
  1. 在回调函数中处理交叉状态的变化。
  1. const callback = (entries, observer) => {
  2. entries.forEach(entry => {
  3. if (entry.isIntersecting) {
  4. // 元素进入视口
  5. } else {
  6. // 元素离开视口
  7. }
  8. });
  9. };

entries 参数是一个包含每个目标元素交叉状态信息的数组。每个 entry 对象都有以下属性:

  • target:观察的目标元素。
  • intersectionRatio:目标元素与视口的交叉比例,值在 0 到 1 之间。
  • isIntersecting:目标元素是否与视口相交。
  • intersectionRect:目标元素与视口的交叉区域的位置和尺寸信息。

options 对象是可选的配置,其中常用的配置选项包括:

  • root:指定观察器的根元素,默认为视口。
  • rootMargin:设置根元素的外边距,用于扩大或缩小交叉区域。
  • threshold:指定交叉比例的阈值,可以是单个数值或由多个数值组成的数组。

应用场景

IntersectionObserver 适用于实现懒加载、无限滚动、广告展示和可视化统计等场景,同样可以判断元素是否在某一个容器内,不会引起回流。

createNodeIterator()

createNodeIterator() 方法是 DOM API 中的一个方法,用于创建一个 NodeIterator 对象,可以用于遍历文档树中的一组 DOM 节点。

通俗一点来讲就是它可以遍历 DOM 结构,把 DOM 变成可遍历的。

比较偏的面试考点

这种方法算是一个比较偏的面试考点,面试官问你怎样实现遍历 DOM 结构?其实就可以用到这个方法。但是大多数程序员答不上来这个问题,因为我们在日常开发中这个方法用得极少。这个方法常在框架源码中体现。

应用

  1. <body>
  2. <div id="app">
  3. <p>hello</p>
  4. <div class="title">标题</div>
  5. <div>
  6. <div class="content">内容</div>
  7. </div>
  8. </div>
  9.  
  10. <script>
  11. const body = document.getElementsByTagName('body')[0]
  12. const item = document.createNodeIterator(body)//让body变成可遍历的
  13. let root = item.nextNode() // 下一层
  14.  
  15. while (root) {
  16. console.log(root);
  17. if (root.nodeType !== 3) {
  18. root.setAttribute('data-index', 123)//给每个节点添加一个属性
  19. }
  20. root = item.nextNode()
  21. }
  22. </script>
  23. </body>

上面代码成功遍历到了各个 DOM 结构:

并且在每个 DOM 节点上都添加了data-index = "123"

getComputedStyle()

getComputedStyle()是一个可以获取当前元素所有最终使用的CSS属性值的方法。返回的是一个CSS样式声明对象。

这个方法有两个参数,第一个参数是你想要获取哪个元素的 CSS ,第二个参数是一个伪元素。

用法

  1. <style>
  2. #box {
  3. width: 200px;
  4. height: 200px;
  5. background-color: cornflowerblue;
  6. position: relative;
  7. }
  8.  
  9. #box::after {
  10. content: "";
  11. width: 50px;
  12. height: 50px;
  13. background: #000;
  14. position: absolute;
  15. top: 0;
  16. left: 0;
  17. }
  18. </style>
  19.  
  20. const box = document.getElementById('box')
  21. const style = window.getComputedStyle(box, 'after')
  22.  
  23. const height = style.getPropertyValue('height')
  24. const width = style.getPropertyValue('width')
  25.  
  26. console.log(style);
  27. console.log(width, height);

上述代码输出结果为:

有一个 id 为 box 容器的 CSS 样式声明对象,以及伪元素的宽高。

requestAnimationFrame()

上面4种方法我们可能用得不是很多,但是requestAnimationFrame方法相对使用较多。requestAnimationFrame() 是一个用于在下一次浏览器重绘之前调用指定函数的方法,它是 HTML5 提供的 API。

与setInterval和setTimeout

requestAnimationFrame的调用频率通常为每秒60次。这意味着我们可以在每次重绘之前更新动画的状态,并确保动画流畅运行,而不会对浏览器的性能造成影响。

setIntervalsetTimeout它可以让我们在指定的时间间隔内重复执行一个操作,不会考虑浏览器的重绘,而是按照指定的时间间隔执行回调函数,可能会被延迟执行,从而影响动画的流畅度。

效果对比

我们设置了两个容器,分别用requestAnimationFrame()方法和setTimeout方法进行平移效果,Js 代码如下所示:

  1. let distance = 0
  2. let box = document.getElementById('box')
  3. let box2 = document.getElementById('box2')
  4.  
  5. window.addEventListener('click', function () {
  6.  
  7. requestAnimationFrame(function move() {
  8. box.style.transform = `translateX(${distance++}px)`
  9. requestAnimationFrame(move)//递归
  10. })
  11.  
  12. setTimeout(function change() {
  13. box2.style.transform = `translateX(${distance++}px)`
  14. setTimeout(change, 17)
  15. }, 17)
  16.  
  17. })

效果图如下:

可能我们肉眼看得不是很清楚,但是确实下面的图形平移没有上面图形流畅,用setTimeout会有卡顿现象。

本文转载于:

https://juejin.cn/post/7242983917603405883

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--你不知道的Js高级方法的更多相关文章

  1. 读JS高级——第五章-引用类型 _记录

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. js实用方法记录-js动态加载css、js脚本文件

    js实用方法记录-动态加载css/js 附送一个加载iframe,h5打开app代码 1. 动态加载js文件到head标签并执行回调 方法调用:dynamicLoadJs('http://www.yi ...

  3. js实用方法记录-简单cookie操作

    js实用方法记录-简单cookie操作 设置cookie:setCookie(名称,值,保存时间,保存域); 获取cookie:setCookie(名称); 移除cookie:setCookie(名称 ...

  4. js实用方法记录-指不定哪天就会用到的js方法

    js实用方法记录-指不定哪天就会用到的js方法 常用或者不常用都有 判断是否在微信浏览器中 测试代码:isWeiXin()==false /** * 是否在微信中 */ function isWeix ...

  5. JS高级---构造函数通过原型添加方法,原型的作用: 共享数据, 节省内存空间

    JS高级---构造函数,通过原型添加方法,原型的作用: 共享数据, 节省内存空间 构造函数 //构造函数 function Person(sex, age) { this.sex = sex; thi ...

  6. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

  7. 翻译连载 | 附录 A:Transducing(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  8. 翻译连载 | 附录 A:Transducing(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  9. 你不知道的JS之 this 和对象原型(一)this 是什么

     原文:你不知道的js系列 JavaScript 的 this 机制并没有那么复杂 为什么会有 this? 在如何使用 this 之前,我们要搞清楚一个问题,为什么要使用 this. 下面的代码尝试去 ...

  10. Ext.js高级组件

    第二章:Ext.js高级组件 grid组件 普通方式 表格面板类Ext.grid.Panel xtype(别名):gridpanel.grid title标题.renderTo渲染至.width宽.h ...

随机推荐

  1. CF-925(已更新:D-F)

    CF 925 补题ing 待更新 后面打算更新D题和power oj上一道区间合并的题(现在才知道是一道洛谷上的原题--) D 分析 ​ 涉及到关于取模的知识,我们的答案要满足三个条件: ai-aj≡ ...

  2. linux 测试网络速率

    1. ethtool ethtool是很强大的查询网卡(嵌入式称为phy芯片)配置的工具,几乎phy芯片芯片手册寄存器能配置的选项,ethtool都能查询到:嵌入式调试phy芯片的时候经常用到该命令: ...

  3. Go语言的100个错误使用场景(48-54)|错误管理

    目录 前言 7. 错误管理 7.1 panicking(#48) 7.2 不清楚何时应该包裹一个 error(#49) 7.3 检查错误类型不够精确(#50) 7.4 检查错误值不够精确(#51) 7 ...

  4. 图文并茂之AES加密

    本文改编自:http://www.sohu.com/a/198681357_505794 假设有一个发送方在向接收方发送消息.如果没有任何加密算法,接收方发送的是一个明文消息:"我是小灰&q ...

  5. 开源大语言模型作为 LangChain 智能体

    概要 开源大型语言模型 (LLMs) 现已达到一种性能水平,使它们适合作为推动智能体工作流的推理引擎: Mixtral 甚至在我们的基准测试中 超过了 GPT-3.5,并且通过微调,其性能可以轻易的得 ...

  6. python 创建动态类

    一般情况下多数是预先定义类 而少数特殊情况就需要去动态创建类了,直接贴代码. class BaseModel(Model): class Meta: database = _tb class_new ...

  7. gitlab/github 设置 SSH

    最近项目要部署到另一台机器上,故要重新 git clone 一下 一开始只是简单的设置 config 里的 user.name 和 user.email,以为就可以 clone(邮箱账户拥有项目的权限 ...

  8. [BUUCTF][Web][极客大挑战 2019]LoveSQL 1

    打开靶机url,页面显示有两个输入框,框中输入123',发现两个框都有sql注入问题 爆出一下错误 You have an error in your SQL syntax; check the ma ...

  9. 学习go语言编程之常量

    什么在常量 在Golang中,常量是指在编译期就已知且不可改变的值. 字面常量 在程序中硬编码的常量值被称为字面常量,如: -12 // 整数类型常量 3.1415926 // 浮点类型常量 3.2+ ...

  10. 用Taro写一个微信小程序——引入外部字体

    小程序直接用.ttf字体文件,在开发工具看没有问题,但是打包编译会提示这个字体文件打包上传不成功. 一.字体文件转换为css 1.打开https://transfonter.org/ 注意选择Base ...