Shadow DOM — Restricted DOM APIs

DEX475 - Work with the DOM

📄 第 183 页 🎬 视频课程

课程章节介绍

同学们,我们这节课来聊一聊Lightning Web Components里一个比较底层的知识点:DOM API的使用限制。这个内容听起来可能有点抽象,但我会尽量把它讲得通俗一些。 首先,你要知道,在Salesforce的Lightning平台上,为了确保每个组件都是独立的、不会相互干扰,Salesforce对不同运行模式下的DOM操作做了特殊处理。 我们先说第一种情况,就是在原来的“合成阴影”模式下,也就是我们常说的Lightning API环境。在这种模式下,当你从组件外部尝试去操作DOM的时候,有一组非常重要的标准DOM API会被直接阻止掉。这些被阻止的方法包括什么呢?像document.getElementById、document.querySelector、document.querySelectorAll,还有document.getElementsByClassName、getElementsByTagName、getElementsByName。注意哦,不仅document级别的方法被阻止,对应body级别的方法也一样会被拦住。为什么要这么做呢?就是为了防止你跨组件去访问或修改别人的DOM结构,从而保证组件的封装性。每个组件就管好自己内部那一亩三分地,你不能随便伸手到别的组件里面去。 那到了比较新的LWS模式,也就是原生阴影模式下,情况就变了。在这种模式下,刚才说的那些API并不会被直接阻止或屏蔽。那这样岂不是就可以随便跨组件访问了?并不是。LWS有它自己的办法:它会把所有组件的ShadowRoot模式强制设为“关闭”(closed)。一旦shadow root是关闭的,外部代码就没法通过元素的shadowRoot属性去拿到它内部的影子树,自然也就访问不到里面的内容了。所以本质上还是保护了封装,只是实现手段不同。 这里要特别提醒大家一个非常重要的坑:如果你在组件里使用了MutationObserver,也就是用来监听DOM变化的那个API,那你一定要记得,在不需要的时候把它断开连接,也就是调用disconnect方法。如果不这样做,很可能会造成内存泄漏。为什么特别强调这个呢?因为影子DOM的多边填充(polyfill)会对这个API做一些修补,如果你没处理好,它可能会一直持有引用,导致内存无法释放。另外还有一点,你的MutationObserver只能在自己的组件模板里观察变化,绝对不能去观察其他组件的影子树,这是做不到的,也是不允许的。 最后,如果你想把自己的代码从旧的合成阴影模式迁移到新的原生阴影模式,Salesforce提供了一个很方便的自动化工具,叫lwc-codemod。它可以帮助你自动转换代码,让你省去很多手动修改的麻烦。 好,这一页的内容我们就讲到这里。大家只要记住三个核心点:合成阴影下API被阻止,原生阴影下shadow root关闭,还有注意MutationObserver的断开和迁移工具。有什么问题,随时可以提出来。

关键词

LWC Lightning Web Components Salesforce