如何同步渲染嵌入式 Elm 模块?
How to render embedded Elm module synchronously?
我正在尝试将 "HelloWorld" 模块嵌入到现有的 HTML 页面中。
我发现模块是异步呈现的(我没有得到呈现的元素
调用 "embed" 后立即执行)。
我想在现有项目中使用 Elm 并重写 JavaScript 的某些部分
在榆树。但是异步渲染使事情变得困难。
有没有同步渲染的方法?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="app.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
var appContainer = document.createElement('div');
Elm.HelloWorld.embed(appContainer);
console.log('Html: ' + appContainer.innerHTML); // Will print an empty string
setTimeout(function() {
console.log('Html: ' + appContainer.innerHTML); // Will print "Hello, World!"
}, 0);
</script>
</body>
</html>
HelloWorld.elm
module HelloWorld exposing (main)
import Html exposing (text)
main =
text "Hello, World!"
更新: 删除了冗余代码。
如今,Elm 不再公开这种钩子。
您基本上有两种不同的方法,一种基于 events ,另一种基于 timing (您已经在使用的 setTimeout()
方法) .
事件驱动方法涉及 MutationObserver Api。
创建一个新的 MutationObserver
,您可以观察 运行 Elm 模块所在的 HTML 节点:这样,您在 DOM 上有一个钩子更新。
一个简单的检查是检查 appContainer
:
的子列表
<body>
<div id="myDiv"></div>
<script type="text/javascript">
var appContainer = document.getElementById('myDiv');
var mo = new MutationObserver(function(mutationRecords, instance) {
for (var i = 0; i < mutationRecords.length; i += 1) {
if (mutationRecords[i].addedNodes.length > 0) {
// a trivial check
console.log('Html: ' + appContainer.innerHTML);
// stop observing, if not needed anymore
mo.disconnect();
}
}
});
mo.observe(appContainer, { childList: true });
Elm.HelloWorld.embed(appContainer);
</script>
</body>
注意上面的代码是假设你的HelloWorld模块在给appContainer
添加children,所以你应该修改方便:
module HelloWorld exposing (main)
import Html exposing (p, text)
main =
p [] [ text "Hello, World!" ]
我正在尝试将 "HelloWorld" 模块嵌入到现有的 HTML 页面中。 我发现模块是异步呈现的(我没有得到呈现的元素 调用 "embed" 后立即执行)。
我想在现有项目中使用 Elm 并重写 JavaScript 的某些部分 在榆树。但是异步渲染使事情变得困难。
有没有同步渲染的方法?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="app.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
var appContainer = document.createElement('div');
Elm.HelloWorld.embed(appContainer);
console.log('Html: ' + appContainer.innerHTML); // Will print an empty string
setTimeout(function() {
console.log('Html: ' + appContainer.innerHTML); // Will print "Hello, World!"
}, 0);
</script>
</body>
</html>
HelloWorld.elm
module HelloWorld exposing (main)
import Html exposing (text)
main =
text "Hello, World!"
更新: 删除了冗余代码。
如今,Elm 不再公开这种钩子。
您基本上有两种不同的方法,一种基于 events ,另一种基于 timing (您已经在使用的 setTimeout()
方法) .
事件驱动方法涉及 MutationObserver Api。
创建一个新的 MutationObserver
,您可以观察 运行 Elm 模块所在的 HTML 节点:这样,您在 DOM 上有一个钩子更新。
一个简单的检查是检查 appContainer
:
<body>
<div id="myDiv"></div>
<script type="text/javascript">
var appContainer = document.getElementById('myDiv');
var mo = new MutationObserver(function(mutationRecords, instance) {
for (var i = 0; i < mutationRecords.length; i += 1) {
if (mutationRecords[i].addedNodes.length > 0) {
// a trivial check
console.log('Html: ' + appContainer.innerHTML);
// stop observing, if not needed anymore
mo.disconnect();
}
}
});
mo.observe(appContainer, { childList: true });
Elm.HelloWorld.embed(appContainer);
</script>
</body>
注意上面的代码是假设你的HelloWorld模块在给appContainer
添加children,所以你应该修改方便:
module HelloWorld exposing (main)
import Html exposing (p, text)
main =
p [] [ text "Hello, World!" ]