MathJax正在重复我的方程式 - 为什么以及如何解决这个问题呢?

时间:2015-03-30 22:59:35

标签: javascript html5 mathjax

我有以下页面(css无用 - 省略):

HTML:

<!DOCTYPE html>
<html lang=en>
    <head>
        <meta charset="UTF-8">
        <title>Command Line</title>
        <script type="text/x-mathjax-config">
        MathJax.Hub.Config({
            extensions: ["http://cs.jsu.edu/mathjax-ext/contrib/forminput/forminput.js"],
            tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
            TeX: {extensions: ["AMSmath.js","AMSsymbols.js"]}
        });
        </script>
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="!!IMPORTANT_JS!!.js"></script>
        <script src="theta.js"></script>
        <script src="cmd.js"></script>
        <link rel="STYLESHEET" type="text/css" href="styles.css">
    </head>
    <header>
        <h1 id="title">COMMAND LINE v.2.0</h1><span id="copy">&copy; 2015 ~ Conor O'Brien</span>
    </header>
    <body>
        <div id="subtitle">Now with $\LaTeX$!</div>
        <div id="out"></div>
        <h3 id="sQ"></h3>
    </body>
    <footer>
        <input type="text" id="cmd">
        <input type="color" id="col">
        <div id="left">&gt;&gt;</div>
    </footer>
</html>

JavaScript的:

$( document ).ready(function(){
    window.t = false;
    $("#col").on("change",function(){
        var d = $q(this).value;
        $q("#out").innerHTML+="<p>Color: <span style=\"color: "+d+";\">"+d.toUpperCase()+", "+Color.hexToRgb(d).v+" - "+linkC("/color "+d,"Use")+"</span>.</p>";
    });
    $("#cmd")[0].addEventListener("keypress",function(e){
        if(e.key=="Enter"){
            submit();
        }
    });
    $("#out").html("Initializing...");
    window.init = function(){
        var d = [br(3)+
                "********* INITIALIZED *********",
                "* Welcome to the experimental *",
                "* JavaScript command line! It *",
                "* will execute exactly like a *",
                "* handheld calculator, having *",
                "* the capacity to execute the *",
                "*        user's inputs.       *",
                "*                             *",
                "* ~-~-~-~-~-~-~-~-~-~-~-~-~-~ *",
                "*                             *",
                "* Type 'help' for environment *",
                "*           commands.         *",
                "*******************************"+br(),
                "<hr>"],i=0;
        function x(d,i){
            $q("#out").innerHTML += (d[i++])||"";
            $q("#out").innerHTML += br();
            if(i<d.length){ setTimeout(x,20,d,i); } else {
                window.t = true;
            }
        }
        setTimeout(x,500,d,i);
    }
    init();
});

function br(x){
    var o = "",x=x||1;
    for(i=0;i<x;i++){
        o+="<br>";
    }
    return o;
}

function $q(i){
    return $(i)[0];
}

function submit(){
    if(t){
        var $out = getOutput();
        if($out){
            var d = "<p id='a"+(el++)+"'>"+$out+"</p>";
            $q("#out").innerHTML += d;
            lines.push(d);
            marker = lines.length;
            location = "file:///C:/Users/Conor%20O%27Brien/Documents/Programming/command%20line%20v.2.0/main.html#sQ";
            $q("#cmd").focus();
            console.log(el);
            MathJax.Hub.Queue(["Typeset",MathJax.Hub,"a"+el+""]);
        }
    }
}

var pi = Math.PI;
var e  = Math.E;

function Reval(str){
    with(Math){var tstr = str.replace(/(.+)\^(.+)/g,"Math.pow($1,$2)");return eval(tstr);}
}

function Dval(str){
    return "$"+str.replace(/(.+)\^(.+)/g,"{$1}^{$2}")+"$";
}

var el = 0;

function getOutput(){
    var val = $q("#cmd").value;
    if(val=="help"){
        $q("#out").innerHTML = "";
        return "<h1>HELP</h1><h2>Commands</h2>"+
        [
            "= help",
            "  - displays help document.",
            "= open {target}",
            "  - displays {target}'s contents.",
            "  - {target} values:",
            "    * options: adjust options with subpoints (i.e. options.{prop} = {1/0} [1=True,0=False])"
        ].join(br())+"<hr>";
    } else if(val=="cls"||val=="clear"){
        $q("#out").innerHTML = "";
        return "Cleared.";
    } else if(val.substr(0,5)=="open "){
        var target = val.substr(5,val.length);
        console.log(target);
        switch(target){
            case "options":

            break;
            default:
                return new Error(target+" is not a valid target!");
            break;
        }
    } else {
        try {
            console.log(val,Reval(val));
            return Dval(val)+br()+"<span class='ans'>"+Reval(val)+"</span>";
        } catch(e) {
            return e;
        }
    }
}

<小时/> 在执行时,这(理想情况下)将能够评估用户的输入(即sin(3)3 + 5^3 / 99.3)。此代码成功完成此操作,但显示它更棘手。我正在使用MathJax正确显示数学,并使用MathJax.Hub.Queue(["Typeset",MathJax.Hub,"a"+el+""]);定位元素a{number}并重做其MathJax。这会以某种方式刷新整个页面,而且,在输入几个条目之后,将开始复制先前的方程式。

我已将其缩小到我认为的解决方案:MathJax有两个可观察的阶段。

  1. 它格式化方程式,然后
  2. 它应用字体。
  3. MathJax函数似乎只在我的代码中执行了两次这两步:一次,在开始时,一次,当函数首次执行时。

    我的问题是,我该如何解决这个问题?我一直试图解决这个问题,但无济于事。

1 个答案:

答案 0 :(得分:1)

您的方法存在一些问题。 MathJax重新处理整个文档的原因是您在el函数中增加submit()的方式。您使用后增量el++,以便在行

之后
var d = "<p id='a"+(el++)+"'>"+$out+"</p>";

el比您要添加的段落的ID大一个。所以稍后你做的时候

MathJax.Hub.Queue(["Typeset",MathJax.Hub,"a"+el+""]);

您传递的ID并未引用新添加的<p>标记,事实上,没有此类ID。当找不到ID时,MathJax会处理整个页面。

对于数学的重复,这是因为您使用innerHTML来更新输出区域。这样做会破坏现有的DOM并用新的DOM替换它(一种非常低效的方法)。这样做会切断MathJax与DOM中现有数学之间的连接,因此MathJax不知道数学已被处理。因此,当它重新处理页面时,它会尝试再次排版数学(尽管在这种情况下它只能创建预览,但这是你看到的重复数学)。

最好不要使用innerHTML替换包含MathJax输出的元素的内容。除了断开MathJax的输出之外,您还会丢失MathJax用于上下文菜单和缩放功能等事件的事件处理程序。最好使用显式DOM操作命令,如document.createElement()appendChild()。这些工作需要更多工作,但效率会更高,特别是对于较长的文档,并且不会导致MathJax问题。

MathJax实际上为以这种方式创建元素提供了一些支持,因此您可以利用这些而不是手动完成所有这些。