【问题标题】:Updating DOM with MathJax and Vue.js使用 MathJax 和 Vue.js 更新 DOM
【发布时间】:2015-11-29 00:34:00
【问题描述】:

(已编辑以包含解决方法,但原始问题仍然存在)

我有一个 HTML 页面,我正在尝试使用 Vue.js(因为它的组件简单易用)和 MathJax(显然是为了布局数学方程式),但它们不能很好地结合在一起。我发现一些关于这个问题的讨论 w/r/t Angular(另一种类似于 Vue 的网络技术,在我有限的理解中),但没有关于 Vue 和 MathJax。

我意识到问题与 Vue 直接操作 HTML DOM 有关,而 MathJax 没有意识到/处理它。 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。除了它没有被呈现为数学(除了有时 - 见下文)。

编辑:我找到了一种解决方法,添加延迟(零毫秒!)然后强制更新,这可行 - 但是否有必要?

无论如何,任何建议将不胜感激!

/抢劫

【问题讨论】:

  • 技术评论:如果您正在编写 HTML5,您的 &lt;doctype html&gt; 声称您这样做了,您不需要 .../&gt; 来处理 &lt;link&gt;&lt;br&gt; 等 void 元素。另外,不要使用&lt;br&gt; 作为间距,使用CSS =) 最后,您缺少&lt;html&gt; 的开头。另外,你是如何测试这个的?来自file:/// 还是使用真正的http 服务器? (如果是第一个,请先尝试使用类似节点的http-serverpython -m SimpleHTTPServer,因为 file:/// 是不可预测的)
  • 谢谢,Mike,我会尝试这些建议,看看它们有什么效果(如果有的话)。
  • 不-尝试了所有这些,没有改变。还是谢谢!
  • 要尝试的另一件事是将用于加载 mathjax 的 &lt;script&gt; 元素放在 &lt;/body&gt; 之前:现在它会加载,然后立即尝试设置页面样式,但页面尚无内容。
  • 未来注意事项:cdn.mathjax.org 即将结束生命周期,请查看mathjax.org/cdn-shutting-down 了解迁移提示。

标签: javascript html mathjax vue.js


【解决方案1】:

警告购买者:我不太了解 vue.js。

但它看起来像一个竞争条件。您正在告诉 MathJax 渲染新内容,但 DOM 还没有新内容。

快速浏览一下 vue.js 文档,$nextTick 似乎应该有所帮助。例如,将其包装在排版调用中:

                this.$nextTick(function() {
                     MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
                 });

这是一个 sn-p(基于您发布到 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>

【讨论】:

  • 甜蜜!这似乎确实起到了作用。我没想过要在 Vue 库中寻找解决方案(呃!)。另外,您的解决方案实际上可以通过此处的“运行代码 sn-p”正确运行。很酷。
  • 我已经更新了答案,因为 cdn.mathjax.org 已接近其生命周期,参见。 mathjax.org/cdn-shutting-down.
  • 彼得,我从未见过你,但我爱你。这让我省了很多麻烦。
  • 很高兴听到这仍然有帮助。如今(使用 MathJax v3),您应该能够通过创建“适配器”(在 mathjax 3 中使用)直接写入 vue 的虚拟 dom;但话说回来,它是如此之快,现在你可能不会再注意到它在动态设置中的渲染了。
猜你喜欢
  • 2019-05-22
  • 2017-02-09
  • 2017-04-18
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 2016-12-09
  • 1970-01-01
  • 2014-09-22
相关资源
最近更新 更多