使用 MathJax 和 Vue.js 更新 DOM
Updating DOM with MathJax and Vue.js
(经过编辑以包含解决方法,但原始问题仍然存在)
我有一个 HTML 页面,我正在尝试使用 Vue.js(因为它的组件又好又简单等等)和 MathJax(显然是为了布局数学方程式)创建的,但是它们在一起玩得不好。我发现了一些关于这个问题的讨论 w/r/t Angular (另一种类似于 Vue 的网络技术,在我有限的理解中)但没有关于 Vue 和 MathJax.
我意识到这个问题与 Vue 直接操作 HTML DOM 而 MathJax 没有实现 it/dealing 有关。 MathJax 中有一些方法声称可以帮助解决这个问题,但要么它们不起作用,要么我没有正确使用它们。
以下是我对最小示例的尝试:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<title>Vue and Mathjax Failing Together</title>
</head>
<body>
<h2>Vue and Mathjax Failing Together</h2>
<div id="app">
<p>The MathJax string renders OK in a Vue data binding (shown using "triple mustache" notation because it's got HTML in it)</p>
{{{ mathjax_paragraph }}}
<hr>
<button v-on:click="createDynamicMarkup">Click to show {{ show_math ? "HTML":"MathJax" }} markup</button>
<p>Here is the dynamic element:</p>
<div id="dynamic_markup_div">
{{{ dynamic_markup }}}
</div>
<br>
<br>
<hr>
<pre>
APP DATA = {{ $data | json }}
</pre>
</div>
<script src='vue.js'></script>
<script>
new Vue({
el: '#app',
data: {
html_paragraph: "<p><i>This is plain HTML</i></p>",
mathjax_paragraph: "<p>\begin{eqnarray*} \frac{20}{3}=6.66= 6\mbox{ hours and } 40 \mbox{ minutes}. \end{eqnarray*} </p>",
dynamic_markup: "<p><i>plain HTML</i></p>",
show_math: false,
math_thing: 0,
},
methods: {
createDynamicMarkup: function(event) {
this.show_math = !this.show_math;
if (this.show_math) {
this.dynamic_markup = this.mathjax_paragraph;
// After a short delay, tell MathJax to update. (So short it's zero!)
// as per https://groups.google.com/forum/#!topic/mathjax-users/EEg35NK2wXU
MathJax.Hub.Queue(
["Delay", MathJax.Callback, 0],
["Typeset", MathJax.Hub, "dynamic_markup_div"]
);
}
else {
this.dynamic_markup = this.html_paragraph;
}
},
},
});
</script>
</body>
</html>
当您第一次加载页面时,会显示普通的 HTML;单击该按钮,应该会显示 MathJax。除了它没有呈现为数学(除了 有时 - 见下文)。
编辑:我找到了一个解决方法,添加延迟(零毫秒!)然后强制更新,这有效 - 但是否有必要?
无论如何,我们将不胜感激!
/罗布
注意买者:我不太了解vue.js。
但这看起来像是一个竞争条件。您告诉 MathJax 呈现新内容,但 DOM 还没有新内容。
快速浏览 vue.js 文档,$nextTick 似乎应该有所帮助。例如,将其包裹在排版调用中:
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
这是一个片段(基于您发布到 MathJax 用户组的片段)。
<!DOCTYPE html>
<html>
<!-- Why does MathJax sometimes not render under Vue?
robcranfill@ "gee-mail" .com
-->
<head>
<meta charset="UTF-8">
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<title>Vue and Mathjax Failing Together</title>
</head>
<body>
<h2>Vue and Mathjax Failing Together</h2>
<div id="app">
<p>The MathJax string renders OK in a Vue data binding (shown using "triple mustache" notation because it's got HTML in it)</p>
{{{ mathjax_paragraph }}}
<hr/>
<button v-on:click="createDynamicMarkup">Click to show {{ show_math ? "HTML":"MathJax" }} markup</button>
<p>Here is the dynamic element:</p>
<div id="dynamic_markup_div">
{{{ dynamic_markup }}}
</div>
<br/>
<br/>
<hr/>
<pre>
APP DATA = {{ $data | json }}
</pre>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.10/vue.min.js'></script>
<script>
new Vue({
el: '#app',
data: {
html_paragraph: "<p><i>This is plain HTML</i></p>",
mathjax_paragraph: "<p>\begin{eqnarray*} \frac{20}{3}=6.66= 6\mbox{ hours and } 40 \mbox{ minutes}. \end{eqnarray*} </p>",
dynamic_markup: "<p><i>plain HTML</i></p>",
show_math: false,
math_thing: 0,
},
methods: {
createDynamicMarkup: function(event) {
this.show_math = !this.show_math;
if (this.show_math) {
this.dynamic_markup = this.mathjax_paragraph;
// Update the whole doc? doesn't work (except in the Javascript debugger! Step over this code and it works!)
// console.log("hello");
// MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
// Update just the DOM element in question? doesn't work
// MathJax.Hub.Queue(["Typeset", MathJax.Hub, "dynamic_markup_div"]);
// Update just the *math* element in question? doesn't work
// math = MathJax.Hub.getAllJax("dynamic_markup_div")[0];
// MathJax.Hub.Queue(["Text", math, this.mathjax_paragraph]);
}
else {
this.dynamic_markup = this.html_paragraph;
}
},
},
});
</script>
</body>
</html>
(经过编辑以包含解决方法,但原始问题仍然存在)
我有一个 HTML 页面,我正在尝试使用 Vue.js(因为它的组件又好又简单等等)和 MathJax(显然是为了布局数学方程式)创建的,但是它们在一起玩得不好。我发现了一些关于这个问题的讨论 w/r/t Angular (另一种类似于 Vue 的网络技术,在我有限的理解中)但没有关于 Vue 和 MathJax.
我意识到这个问题与 Vue 直接操作 HTML DOM 而 MathJax 没有实现 it/dealing 有关。 MathJax 中有一些方法声称可以帮助解决这个问题,但要么它们不起作用,要么我没有正确使用它们。
以下是我对最小示例的尝试:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<title>Vue and Mathjax Failing Together</title>
</head>
<body>
<h2>Vue and Mathjax Failing Together</h2>
<div id="app">
<p>The MathJax string renders OK in a Vue data binding (shown using "triple mustache" notation because it's got HTML in it)</p>
{{{ mathjax_paragraph }}}
<hr>
<button v-on:click="createDynamicMarkup">Click to show {{ show_math ? "HTML":"MathJax" }} markup</button>
<p>Here is the dynamic element:</p>
<div id="dynamic_markup_div">
{{{ dynamic_markup }}}
</div>
<br>
<br>
<hr>
<pre>
APP DATA = {{ $data | json }}
</pre>
</div>
<script src='vue.js'></script>
<script>
new Vue({
el: '#app',
data: {
html_paragraph: "<p><i>This is plain HTML</i></p>",
mathjax_paragraph: "<p>\begin{eqnarray*} \frac{20}{3}=6.66= 6\mbox{ hours and } 40 \mbox{ minutes}. \end{eqnarray*} </p>",
dynamic_markup: "<p><i>plain HTML</i></p>",
show_math: false,
math_thing: 0,
},
methods: {
createDynamicMarkup: function(event) {
this.show_math = !this.show_math;
if (this.show_math) {
this.dynamic_markup = this.mathjax_paragraph;
// After a short delay, tell MathJax to update. (So short it's zero!)
// as per https://groups.google.com/forum/#!topic/mathjax-users/EEg35NK2wXU
MathJax.Hub.Queue(
["Delay", MathJax.Callback, 0],
["Typeset", MathJax.Hub, "dynamic_markup_div"]
);
}
else {
this.dynamic_markup = this.html_paragraph;
}
},
},
});
</script>
</body>
</html>
当您第一次加载页面时,会显示普通的 HTML;单击该按钮,应该会显示 MathJax。除了它没有呈现为数学(除了 有时 - 见下文)。
编辑:我找到了一个解决方法,添加延迟(零毫秒!)然后强制更新,这有效 - 但是否有必要?
无论如何,我们将不胜感激!
/罗布
注意买者:我不太了解vue.js。
但这看起来像是一个竞争条件。您告诉 MathJax 呈现新内容,但 DOM 还没有新内容。
快速浏览 vue.js 文档,$nextTick 似乎应该有所帮助。例如,将其包裹在排版调用中:
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
这是一个片段(基于您发布到 MathJax 用户组的片段)。
<!DOCTYPE html>
<html>
<!-- Why does MathJax sometimes not render under Vue?
robcranfill@ "gee-mail" .com
-->
<head>
<meta charset="UTF-8">
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<title>Vue and Mathjax Failing Together</title>
</head>
<body>
<h2>Vue and Mathjax Failing Together</h2>
<div id="app">
<p>The MathJax string renders OK in a Vue data binding (shown using "triple mustache" notation because it's got HTML in it)</p>
{{{ mathjax_paragraph }}}
<hr/>
<button v-on:click="createDynamicMarkup">Click to show {{ show_math ? "HTML":"MathJax" }} markup</button>
<p>Here is the dynamic element:</p>
<div id="dynamic_markup_div">
{{{ dynamic_markup }}}
</div>
<br/>
<br/>
<hr/>
<pre>
APP DATA = {{ $data | json }}
</pre>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.10/vue.min.js'></script>
<script>
new Vue({
el: '#app',
data: {
html_paragraph: "<p><i>This is plain HTML</i></p>",
mathjax_paragraph: "<p>\begin{eqnarray*} \frac{20}{3}=6.66= 6\mbox{ hours and } 40 \mbox{ minutes}. \end{eqnarray*} </p>",
dynamic_markup: "<p><i>plain HTML</i></p>",
show_math: false,
math_thing: 0,
},
methods: {
createDynamicMarkup: function(event) {
this.show_math = !this.show_math;
if (this.show_math) {
this.dynamic_markup = this.mathjax_paragraph;
// Update the whole doc? doesn't work (except in the Javascript debugger! Step over this code and it works!)
// console.log("hello");
// MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
// Update just the DOM element in question? doesn't work
// MathJax.Hub.Queue(["Typeset", MathJax.Hub, "dynamic_markup_div"]);
// Update just the *math* element in question? doesn't work
// math = MathJax.Hub.getAllJax("dynamic_markup_div")[0];
// MathJax.Hub.Queue(["Text", math, this.mathjax_paragraph]);
}
else {
this.dynamic_markup = this.html_paragraph;
}
},
},
});
</script>
</body>
</html>