我有一个包含MathML的HTML。现在,我想指定这样,只有当浏览器不支持MathJax 时,浏览器才会加载MathML。
背景
截至2018年秋季,火狐、卡米诺和Safari似乎支持MathML,而大多数其他浏览器,特别是Chrome、Internet和Opera则不支持它(参见维基百科的MathML条目)。MathJax是一种解决方案,可以强制浏览器解释MathML,但它有一些限制,比如还没有(还没有?)支持行跨/跨(请参阅问题所在);此外,MathML在表示语义方面占优势,这对于非可视浏览器或客户端至关重要。
因此,我想有条件地加载MathJax --仅当浏览器不支持MathML时。
我应该注意,如果MathJax只是以一种简单的方式加载,例如火狐也使用MathJax重新呈现MathML,出于上述原因,我想避免这种情况(另外,浪费客户端的资源)。MathJax不应该加载(或触发)火狐等。
我现在的测量
下面是我想出的一个粗解决方案的脚本,所以如果浏览器是Chrome (或类似的)、Konqueror或MSIE,在Mathjax正式文档中引用"动态加载MathJax“,则会加载Mathjax。
<script>
if (navigator.userAgent.match(/((Chrom(e|ium)|Konqueror)\/?|MSIE \d)/)) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML";
document.getElementsByTagName("head")[0].appendChild(script);
}
</script>
但这有一些明显的局限性。是否适用于上述浏览器的所有版本?不能保证此条件是否适用于他们的未来版本。或者,这些浏览器可能在其未来的版本中开始支持MathML。实际上不支持MathML的其他浏览器不被考虑,等等。
例如,我认为一个更好的方法是,只有当浏览器不支持MathJax标记时才加载<math>
。
实现MathJax的条件加载的最佳方法是什么?或者,任何比上面的代码片段更好的东西都会被感激。
发布于 2022-08-08 09:23:25
摘要
可以说,最好的解决方案是加载一小块JavaScript代码以查找/确定浏览器是否可以解释MathML,并根据其评估有选择地加载MathJax JavaScript库。
简略历史语境
解决方案的一个很好的起点过去是mozilla.org中的描述,特别是"回退“部分。不幸的是,一些实际代码已经过时,显然不再维护了,可能是在2017年关闭mathjax.org上的cdn服务器之后。然而,报告中提出的关于如何处理这一问题的几项政策仍然是一个良好的起点。以下是一个简短的总结:
现在,我正在深入研究第三个选项(我认为是最好的)。
详细解决方案
我已经发布了代码以实现第三种策略(从原始代码中更新),并在Github.com和Github.io上发布更多信息,以供直接使用。以下是它的核心。
原始代码的算法依赖于浏览器处理MathML的可视化外观。因此,如果将来的Chrome版本能够处理MathML,那么这个代码段仍然可以正常工作。这不会为非可视web浏览器加载MathJax (我认为这是正确的态度,因为我相信MathJax无论如何都假定了可视环境)。
简而言之,在<head>
环境中插入以下代码即可工作,根据浏览器的不同,MathJax Ver.3.2.2是有选择地加载的。该代码是原始代码的更新和稍微扩展的版本(很可能是由王德烈编写的)。2022年夏天,MathJax托管在cloudflare上。
<script>
(function(){window.addEventListener("load",function(){
var a,b;
if( document.body.getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML","math")[0]
&&(document.body.insertAdjacentHTML(
"afterbegin",
"<div style='border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px;'><math xmlns='http://www.w3.org/1998/Math/MathML'><mpadded height='23px' width='77px'></mpadded></math></div>"
),
b=document.body.firstChild,
a=b.firstChild.firstChild.getBoundingClientRect(),
document.body.removeChild(b),
1 < Math.abs(a.height-23) || 1 < Math.abs(a.width-77)
)
){
a = document.createElement("script");
a.src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js",
document.head.appendChild(a);
document.getElementById("q2").innerHTML = "(Chrome-like)"; // Your arbitrary extra code!
} else {
document.getElementById("q2").innerHTML = "(Firefox/Safari)"; // Your arbitrary extra code!
}
})})();
</script>
或者,如果您喜欢MathJax Ver。2,将代码中的URI替换为:CHTML
或者,如果您愿意,可以使用KaTeX或其他替代方案来代替MathJax。在上面提到的Github站点中,我描述了几种方法的优缺点。
示例MathML/HTML
下面是一个示例MathML/HTML代码,其中也使用了数组模式。HTML与上面描述的JavaScript代码相结合,为Firefox和Chrome生成了几乎相同的可视化输出(参见截图)。
<body>
<h2>Test <span id="q2"></span></h2>
<p>
Using <i>a</i>, the formula
<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="\sqrt{a}">
<msqrt>
<mi>a</mi>
</msqrt>
</math>
is displayed inline.
</p>
<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="1 = \sqrt{1} = \sqrt{(-1)\times(-1)} \ne \sqrt{-1}\times\sqrt{-1} ">
<mtable class="m-eqnarray-starred" displaystyle="true" style="display: block; margin-top: 1.0em; margin-bottom: 2.0em">
<mtr>
<mtd columnalign="right"> <mn>1</mn> </mtd>
<mtd columnalign="left"> <mo>=</mo> </mtd>
<mtd columnalign="left"> <msqrt> <mn>1</mn> </msqrt> </mtd>
</mtr><mtr>
<mtd columnalign="right"> </mtd>
<mtd columnalign="left"> <mo>=</mo> </mtd>
<mtd columnalign="left"> <msqrt> <mrow>
<mrow>
<mo form="prefix">(</mo> <mo>-</mo> <mn>1</mn> <mo form="postfix">)</mo>
</mrow>
<mo>×</mo>
<mrow>
<mo form="prefix">(</mo> <mo>-</mo> <mn>1</mn> <mo form="postfix">)</mo>
</mrow>
</mrow> </msqrt> </mtd>
</mtr> <mtr>
<mtd columnalign="right"> </mtd>
<mtd columnalign="left"> <mo>≠</mo> </mtd>
<mtd columnalign="left">
<msqrt> <mo>-</mo> <mn>1</mn> </msqrt>
<mo>×</mo>
<msqrt> <mo>-</mo> <mn>1</mn> </msqrt>
</mtd>
</mtr>
</mtable>
</math>
</body>
基于用户代理的评估述评
最后,我对基于用户代理的选择性加载MathJax的算法进行了简要的评述.下面是它的JavaScript代码示例。
if (navigator.userAgent.match(
/((Chrom(e|ium)|Konqueror|Edge?|Opera|OPR)\/?|MSIE \d)/)) { // ...
}
一个主要的问题是Chrome在默认情况下向Firefox发送类似的用户代理,这是非常令人困惑的。因此,我不认为基于用户代理的评估是个好主意,除了这样的策略原则上需要开发人员和用户不断地维护/更新脚本之外,考虑到未来版本的浏览器可能随时都可以处理MathML。
https://stackoverflow.com/questions/53021321
复制相似问题