本系列文章的第10篇,专注于探索JavaScript及其构建组件。在识别和描述核心元素的过程中,我们也分享了一些在构建SessionStack时使用的经验法则,SessionStack是一个JavaScript工具,用于通过像素完美的会话重放来识别、可视化和重现Web应用程序中的错误。
如果你错过了之前的文章,可以在这里找到它们:
- 引擎、运行时和调用栈概述
- Google V8引擎内部详解+ 5个编写优化代码的技巧
- 内存管理+如何处理4种常见的内存泄漏
- 事件循环和异步编程的崛起+使用async/await进行更好编码的5种方法
- WebSockets和HTTP/2的深入探讨+SSE的正确选择方法
- 与WebAssembly的比较+在某些情况下,为什么使用WebAssembly比JavaScript更好
- Web Workers的构建块+ 5种使用它们的情况
- Service Workers、它们的生命周期和用例
- Web Push通知的机制
Web应用程序在客户端越来越重,原因有很多,例如需要更丰富的UI来容纳更复杂的应用程序,实时计算等等。
增加的复杂性使得在Web应用程序的生命周期中的每个给定时刻知道UI的确切状态变得更加困难。
如果你正在构建某种框架或只是一个库,例如必须根据DOM做出反应并执行某些操作,则这变得更加困难。
概述
MutationObserver是现代浏览器提供的Web API,用于检测DOM中的更改。使用此API,可以监听新添加或删除的节点、属性更改或文本节点的文本内容更改。
为什么要这样做?
MutationObserver API非常实用的情况有很多。例如:
- 你想通知你的Web应用程序访问者页面上发生了某些更改。
- 你正在开发一个新的花哨JavaScript框架,该框架根据DOM更改动态加载JavaScript模块。
- 你可能正在开发WYSIWYG编辑器,尝试实现撤消/重做功能。通过利用MutationObserver API,你可以知道在任何给定时刻进行了哪些更改,因此可以轻松地撤消它们。
这些只是MutationObserver可以提供帮助的几个例子。
如何使用MutationObserver
将MutationObserver
实现到你的应用程序中相当容易。你需要通过传递一个函数来创建一个MutationObserver
实例,每次发生变化时都会调用该函数。函数的第一个参数是在单个批次中发生的所有变化的集合。每个变化提供其类型和发生的更改的信息。
创建的对象有三种方法:
observe
-开始监听更改。接受两个参数-你要观察的DOM节点和一个设置对象disconnect
-停止监听更改takeRecords
-在调用回调之前返回最后一批更改。
以下代码片段显示如何开始观察:
现在,假设你在DOM中有一些非常简单的div
:
使用jQuery,你可以从该div中删除class
属性:
由于我们已经开始观察,因此在调用mutationObserver.observe(...)
之后,我们将在相应的MutationRecord的控制台中看到日志:
这是由删除class
属性引起的变化。
最后,在完成工作后停止观察DOM,可以执行以下操作:如今,MutationObserver
得到了广泛的支持:
其他选择
然而,MutationObserver
并不是一直存在的。那么在 MutationObserver
出现之前,开发者是如何解决这个问题的呢?
有一些其他的选择:
- 轮询
- MutationEvents
- CSS 动画
轮询
最简单、最不复杂的方式是轮询。使用浏览器的 setInterval WebAPI,你可以设置一个任务,定期检查是否发生了任何变化。当然,这种方法会显著降低 Web 应用程序/网站的性能。
MutationEvents
在 2000 年,MutationEvents API 被引入。虽然很有用,但变异事件会在 DOM 的每一次更改时触发,这会导致性能问题。现在 MutationEvents
API 已被弃用,现代浏览器很快将停止支持它。
这是 MutationEvents
的浏览器支持情况:
CSS 动画
一种有些奇怪的替代方法是依赖于 CSS 动画。这可能听起来有点令人困惑。基本上,这个想法是创建一个动画,一旦一个元素被添加到 DOM 中,就会被触发。当动画开始时,animationstart
事件将被触发:如果你已经将事件处理程序附加到该事件上,你就会知道元素何时被添加到 DOM 中。动画的执行时间应该很短,以至于用户几乎看不到它。
首先,我们需要一个父元素,在其中监听节点插入:
为了获取节点插入的句柄,我们需要设置一系列 关键帧 动画,这些动画将在插入节点时开始:
关键帧创建完毕后,需要将动画应用于你想要监听的元素。请注意小的持续时间 - 它们会放松浏览器中的动画印记:
这将为 container-element
的所有子节点添加动画。当动画结束时,插入事件将被触发。
我们需要一个 JavaScript 函数来作为事件监听器。在函数内部,必须进行初始的 event.animationName
检查,以确保它是我们想要的动画。
现在是时候将事件监听器添加到父级上了:
这是 CSS 动画的浏览器支持情况:
MutationObserver
在上述解决方案中提供了许多优势。本质上,它涵盖了可能发生在 DOM 中的每一个变化,而且它更加优化,因为它批量触发更改。除此之外,MutationObserver
被所有主要现代浏览器支持,还有一些使用 MutationEvents
的 polyfill。
MutationObserver
在 SessionStack 库中占据了中心位置。
一旦将 SessionStack 库集成到你的 Web 应用程序中,它就开始收集数据,如 DOM 更改、网络请求、异常、调试消息等,并将其发送到我们的服务器。SessionStack 使用这些数据来重新创建你的用户所发生的一切,并以与你的用户相同的方式显示你的产品问题。很多用户认为 SessionStack 记录了实际的视频 - 它并没有。记录实际视频非常耗费资源,而我们收集的少量数据非常轻量级,不会影响你的 Web 应用程序的用户体验和性能。
如果你想要 尝试 SessionStack,可以使用免费计划。
评论(0)