JavaScript常用API有什么,含义和用法是怎样的
Admin 2022-07-12 群英技术资讯 289 次浏览
MutationObserver 是一个可以监听 DOM 结构变化的接口。
当 DOM 对象树发生任何变动时,MutationObserver 会得到通知。
MutationObserver 是一个构造器,接受一个 callback 参数,用来处理节点变化的回调函数,返回两个参数:
mutations
:节点变化记录列表(sequence<MutationRecord>)
observer
:构造 MutationObserver 对象。
MutationObserver 对象有三个方法,分别如下:
observe
:设置观察目标,接受两个参数,target:观察目标,options:通过对象成员来设置观察选项
disconnect
:阻止观察者观察任何改变
takeRecords
:清空记录队列并返回里面的内容
//选择一个需要观察的节点 var targetNode = document.getElementById('root') // 设置observer的配置选项 var config = { attributes: true, childList: true, subtree: true } // 当节点发生变化时的需要执行的函数 var callback = function (mutationsList, observer) { for (var mutation of mutationsList) { if (mutation.type == 'childList') { console.log('A child node has been added or removed.') } else if (mutation.type == 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.') } } } // 创建一个observer示例与回调函数相关联 var observer = new MutationObserver(callback) //使用配置文件对目标节点进行观测 observer.observe(targetNode, config) // 停止观测 observer.disconnect()
observe 方法中 options 参数有已下几个选项:
childList
:设置 true,表示观察目标子节点的变化,比如添加或者删除目标子节点,不包括修改子节点以及子节点后代的变化
attributes
:设置 true,表示观察目标属性的改变
characterData
:设置 true,表示观察目标数据的改变
subtree
:设置为 true,目标以及目标的后代改变都会观察
attributeOldValue
:如果属性为 true 或者省略,则相当于设置为 true,表示需要记录改变前的目标属性值,设置了 attributeOldValue 可以省略 attributes 设置
characterDataOldValue
:如果 characterData 为 true 或省略,则相当于设置为 true,表示需要记录改变之前的目标数据,设置了 characterDataOldValue 可以省略 characterData 设置
attributeFilter
:如果不是所有的属性改变都需要被观察,并且 attributes 设置为 true 或者被忽略,那么设置一个需要观察的属性本地名称(不需要命名空间)的列表
MutationObserver 有以下特点:
当 DOM 发生变动会触发 MutationObserver 事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说 DOM 发生变动立刻会触发相应的事件;MutationObserver 则是异步触发,DOM 发生变动以后,并不会马上触发,而是要等到当前所有 DOM 操作都结束后才触发。
举例来说,如果在文档中连续插入 1000 个段落(p 元素),会连续触发 1000 个插入事件,执行每个事件的回调函数,这很可能造成浏览器的卡顿;而 MutationObserver 完全不同,只在 1000 个段落都插入结束后才会触发,而且只触发一次,这样较少了 DOM 的频繁变动,大大有利于性能。
网页开发时,常常需要了解某个元素是否进入了"视口"(viewport),即用户能不能看到它。
传统的实现方法是,监听到 scroll 事件后,调用目标元素的 getBoundingClientRect()方法,得到它对应于视口左上角的坐标,再判断是否在视口之内。这种方法的缺点是,由于 scroll 事件密集发生,计算量很大,容易造成性能问题。
目前有一个新的 IntersectionObserver API,可以自动"观察"元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。
IntersectionObserver 是浏览器原生提供的构造函数,接受两个参数:callback 是可见性变化时的回调函数,option 是配置对象(该参数可选)。
var io = new IntersectionObserver(callback, option) // 开始观察 io.observe(document.getElementById('example')) // 停止观察 io.unobserve(element) // 关闭观察器 io.disconnect()
如果要观察多个节点,就要多次调用这个方法。
io.observe(elementA) io.observe(elementB)
目标元素的可见性变化时,就会调用观察器的回调函数 callback。callback 一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)。
var io = new IntersectionObserver((entries) => { console.log(entries) })
callback 函数的参数(entries)是一个数组,每个成员都是一个 IntersectionObserverEntry 对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries 数组就会有两个成员。
time
:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
target
:被观察的目标元素,是一个 DOM 节点对象
isIntersecting
: 目标是否可见
rootBounds
:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回 null
boundingClientRect
:目标元素的矩形区域的信息
intersectionRect
:目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio
:目标元素的可见比例,即 intersectionRect 占 boundingClientRect 的比例,完全可见时为 1,完全不可见时小于等于 0
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style> #div1 { position: sticky; top: 0; height: 50px; line-height: 50px; text-align: center; background: black; color: #ffffff; font-size: 18px; } </style> </head> <body> <div id="div1">首页</div> <div style="height: 1000px;"></div> <div id="div2" style="height: 100px; background: red;"></div> <script> var div2 = document.getElementById('div2') let observer = new IntersectionObserver( function (entries) { entries.forEach(function (element, index) { console.log(element) if (element.isIntersecting) { div1.innerText = '我出来了' } else { div1.innerText = '首页' } }) }, { root: null, threshold: [0, 1] } ) observer.observe(div2) </script> </body> </html>
相比于 getBoundingClientRect,它的优点是不会引起重绘回流。
图片懒加载的原理主要是判断当前图片是否到了可视区域这一核心逻辑实现的。这样可以节省带宽,提高网页性能。传统的突破懒加载是通过监听 scroll 事件实现的,但是 scroll 事件会在很短的时间内触发很多次,严重影响页面性能。为提高页面性能,我们可以使用 IntersectionObserver 来实现图片懒加载。
const imgs = document.querySelectorAll('img[data-src]') const config = { rootMargin: '0px', threshold: 0 } let observer = new IntersectionObserver((entries, self) => { entries.forEach((entry) => { if (entry.isIntersecting) { let img = entry.target let src = img.dataset.src if (src) { img.src = src img.removeAttribute('data-src') } // 解除观察 self.unobserve(entry.target) } }) }, config) imgs.forEach((image) => { observer.observe(image) })
无限滚动(infinite scroll)的实现也很简单。
var intersectionObserver = new IntersectionObserver(function (entries) { // 如果不可见,就返回 if (entries[0].intersectionRatio <= 0) return loadItems(10) console.log('Loaded new items') }) // 开始观察 intersectionObserver.observe(document.querySelector('.scrollerFooter'))
DOM2 Style 在 document.defaultView
上增加了 getComputedStyle()方法,该方法返回一个 CSSStyleDeclaration
对象(与 style 属性的类型一样),包含元素的计算样式。
document.defaultView.getComputedStyle(element[,pseudo-element]) // or window.getComputedStyle(element[,pseudo-element])
这个方法接收两个参数:要取得计算样式的元素和伪元素字符串(如":after")。如果不需要查询伪元素,则第二个参数可以传 null。
<!DOCTYPE html> <html> <head> <style type="text/css"> #myDiv { background-color: blue; width: 100px; height: 200px; } </style> </head> <body> <div id="myDiv" style="background-color: red; border: 1px solid black"></div> </body> <script> function getStyleByAttr(obj, name) { return window.getComputedStyle ? window.getComputedStyle(obj, null)[name] : obj.currentStyle[name] } let node = document.getElementById('myDiv') console.log(getStyleByAttr(node, 'backgroundColor')) console.log(getStyleByAttr(node, 'width')) console.log(getStyleByAttr(node, 'height')) console.log(getStyleByAttr(node, 'border')) </script> </html>
getComputedStyle 和 element.style 的相同点就是二者返回的都是 CSSStyleDeclaration 对象。而不同点就是:
element.style 读取的只是元素的内联样式,即写在元素的 style 属性上的样式;而 getComputedStyle 读取的样式是最终样式,包括了内联样式、嵌入样式和外部样式。
element.style 既支持读也支持写,我们通过 element.style 即可改写元素的样式。而 getComputedStyle 仅支持读并不支持写入。我们可以通过使用 getComputedStyle 读取样式,通过 element.style 修改样式
getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
let DOMRect = object.getBoundingClientRect()
它的返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合,就是该元素的 CSS 边框大小。
返回的结果是包含完整元素的最小矩形,并且拥有 left, top, right, bottom, x, y, width, 和 height 这几个以像素为单位的只读属性用于描述整个边框。除了 width 和 height 以外的属性是相对于视图窗口的左上角来计算的。
以前的写法是通过 offsetParent 找到元素到定位父级元素,直至递归到顶级元素 body 或 html。
// 获取dom元素相对于网页左上角定位的距离 function offset(el) { var top = 0 var left = 0 do { top += el.offsetTop left += el.offsetLeft } while ((el = el.offsetParent)) // 存在兼容性问题,需要兼容 return { top: top, left: left } } var odiv = document.getElementsByClassName('markdown-body') offset(a[0]) // {top: 271, left: 136}
现在根据 getBoundingClientRect 这个 api,可以写成这样:
var positionX = this.getBoundingClientRect().left + document.documentElement.scrollLeft var positionY = this.getBoundingClientRect().top + document.documentElement.scrollTop
function isElView(el) { var top = el.getBoundingClientRect().top // 元素顶端到可见区域顶端的距离 var bottom = el.getBoundingClientRect().bottom // 元素底部端到可见区域顶端的距离 var se = document.documentElement.clientHeight // 浏览器可见区域高度。 if (top < se && bottom > 0) { return true } else if (top >= se || bottom <= 0) { // 不可见 } return false }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本篇文章给大家带来了关于javascript的相关知识,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),下面一起来看一下JavaScript webpack5配置及使用基本介绍,希望对大家有帮助。
本文依旧给大家分享Javascript设计模式的内容,这篇主要介绍Javascript适配器模式,那么究竟Javascript适配器模式是什么呢?有什么用?如何实现?接下来我们一一了解清楚。
本篇文章给大家带来了JavaScript中对象解构用法解析的相关知识,希望对大家有帮助。
我们平常在浏览一些网站的时候,经常能看到选项卡展示功能,其好处就是节约页面空间,我们只要点击不同的区域,就能展现不同的内容,这样能比较合理的展示内容。那么JS是怎样实现选项卡插件的呢?
这篇文章主要为大家介绍了Vue项目怎样用defineCustomElement定义组件,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008