【问题标题】:Prevent my Elm app from crashing when a 3rd party changes the DOM防止我的 Elm 应用程序在第 3 方更改 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,有没有办法得到通知?这样我什至可以通知用户他们有一个干扰应用程序的扩展程序。

【问题讨论】:

标签: elm browser-extension virtual-dom


【解决方案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>

被翻译成

&lt;span&gt;&lt;font&gt;&lt;font&gt;Insurello. &lt;/font&gt;&lt;font&gt;The right compensation for everyone&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;

此方法可避免尝试编辑跨度,而是将其替换为新跨度。添加节点后,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 eventsDOMSubtreeModified 也可以提供帮助,但它们已被弃用。

    【讨论】:

    • 这将通知您所有更改,包括 Elm 本身修改 DOM,而不仅仅是第 3 方所做的更改。除非您能以某种方式过滤掉 Elm 所做的更改,否则这是行不通的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    相关资源
    最近更新 更多