防止我的 Elm 应用程序在第 3 方更改 DOM 时崩溃
Posted
技术标签:
【中文标题】防止我的 Elm 应用程序在第 3 方更改 DOM 时崩溃【英文标题】:Prevent my Elm app from crashing when a 3rd party changes the DOM 【发布时间】:2020-12-24 08:13:49 【问题描述】:我有一个 Elm 应用程序。不久前,当我使用 FontAwesome 图标时,我意识到我的应用程序在本地崩溃了。我开始明白这是因为我选择了 SVG 图标,因此 FontAwesome 正在修改 DOM。这与 Elm 的 VDOM 机制相冲突。
这很容易解决——我迁移到了使用伪元素的 CSS 版本的 FontAwesome。最近一些用户抱怨生产中的应用程序冻结,他们显示了与我的日志数据不匹配的状态截图。过了一段时间,我才意识到所有这些用户都有谷歌翻译自动为他们翻译页面。 Google Translate clearly alters the DOM,所以 Elm 崩溃我并不感到惊讶。
如何防止我的 Elm 应用崩溃?如果第 3 方更改 DOM,有没有办法得到通知?这样我什至可以通知用户他们有一个干扰应用程序的扩展程序。
【问题讨论】:
我的直接想法是看看 React github.com/facebook/react/issues/11538 会发生什么 感谢@SimonH,提供有用的资源。 关注了该线程,React's fix was not to React itself but to the reactjs.org website。一个explanation here. 我用同样的问题创建了this issue。 【参考方案1】:看看这里 - How we made Elm and Google Translate work together。
他们的方法是使用下面的函数劫持 Elm 在 dom 更新期间调用的 Elm replaceData
方法。你可以在让 Elm 控制 dom 之前运行它。
htmlFontElement.prototype.replaceData =
function replaceData(_0, _1, string)
this.parentNode.replaceChild(
document.createTextNode(string),
this
);
;
显然,“Google 翻译将 DOM 中的每个文本节点替换为包含至少一个标签的标签 - 每个句子一个标签”。例如:
<span>Insurello. Rätt ersättning till alla</span>
被翻译成
<span><font><font>Insurello. </font><font>The right compensation for everyone</font></font></span>
此方法可避免尝试编辑跨度,而是将其替换为新跨度。添加节点后,Google 翻译将翻译该文本。
【讨论】:
谢谢!我刚刚在 Elm 时事通讯中也遇到过这个问题,它确实适用于 Google 翻译。【参考方案2】:此问题与 Elm 中的 Google Maps 或 Google Places Autocomplete 的问题密切相关。我过去使用的解决方案是提供一个没有子元素的 div,其 id 可以从 javascript 中指向。
因为 div 没有子元素,所以 Elm 不会在后台检查它是否在内部发生了变化。
查看此blog post 或谷歌“榆树地图”以获取有关如何执行此操作的说明
-- 编辑-- 我已经更好地阅读了这个问题,这可能不适用于谷歌翻译问题,因为它会更改整个 DOM 中的所有文本。我将把它留在这里,以防问题带来更多的人,他们在第 3 方更改 DOM 时会遇到更多常见问题
【讨论】:
【参考方案3】:我遇到了和你一样的问题,并通过迁移到 Elm-FontAwesome 库来解决它。基本上你所要做的就是替换这个语法:
i [ Svga.class "fas fa-check" ] []
用这个:
Icon.viewIcon Icon.check
您可以查看示例项目以了解更多详细信息:https://github.com/Lattyware/elm-fontawesome-example
【讨论】:
嗨!欢迎来到 SO!是的,这听起来是让 Elm 和 FontAwesome SVG 图标一起工作的另一种方式,但我真正感兴趣的是如何处理这类问题。【参考方案4】:我不知道如何防止崩溃,但我认为您应该能够使用 current mutation observer API 注册对 DOM 的更改。
在此之前有几个 deprecated mutation events 像 DOMSubtreeModified
也可以提供帮助,但它们已被弃用。
【讨论】:
这将通知您所有更改,包括 Elm 本身修改 DOM,而不仅仅是第 3 方所做的更改。除非您能以某种方式过滤掉 Elm 所做的更改,否则这是行不通的。以上是关于防止我的 Elm 应用程序在第 3 方更改 DOM 时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
我的 javascript 和移植的 elm 之间的 UI 滞后