端口和DOM渲染

时间:2016-09-09 04:46:27

标签: dom codemirror elm elm-port

尝试在我的Elm应用程序中使用CodeMirror。

我从update函数绑定一个textarea:

( ..., runCodemirror textAreaId)

runCodemirror是一个端口:

port runCodemirror : String -> Cmd msg

问题是事件ports.runCodemirror在DOM中出现textarea之前触发。

我尝试用setTimeout来解决这个问题:

app.ports.runCodemirror.subscribe(
  function (textAreaId) {
    setTimeout(
      function() {
        CodeMirror.fromTextArea(document.getElementById(textAreaId));
      },
      100
    );
  }
);

但它很难看。 100毫秒太慢,我看到一个闪烁。

我拥有的其他选项:将CodeMirror与不可见的textarea或MutationObserver API绑定。

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用DOM mutation observers来监视DOM中的更改,并在这些事件触发时创建JS对象,这样您根本不需要使用端口。

ArriveJS为此功能提供了一个很好的包装器,因此您可以执行以下操作:

document.arrive(".code-mirror", function() {
  CodeMirror.fromTextArea(this)
})

您可以通过向data-中的元素添加Elm属性并在JS方面阅读它们来进一步实现此目的:

document.arrive(".code-mirror", function() {
  const lineNumbers = this.getAttribute('data-line-numbers') 
  CodeMirror.fromTextArea(this, {
    lineNumbers: lineNumbers
  })
})

答案 1 :(得分:0)

如果你开放滥用json解码器,你可以使用它们在元素首次出现在DOM中时运行代码。我在这里写了这个方法:https://medium.com/@prozacchiwawa/the-i-m-stupid-elm-language-nugget-7-8d3efd525e3e#.3hatcdfl3。否则,MutationObserver即可。