Angular中使用MathJax遇到的一些问题


Posted in Javascript onDecember 15, 2017

前言

话说我本来是倾向于 KaTeX 的,因为我感觉他很快,而且 MathJax 似乎很难配。但是大家表示对缺少功能的 KaTeX 并无好感,给我提供了一些钻研 MathJax 的动力。

MathJax简介

MathJax是一款运行在浏览器中的开源数学符号渲染引擎,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。MathJax项目于2009年开始,发起人有American Mathematical Society, Design Science等,还有众多的支持者,个人感觉MathJax会成为今后数学符号渲染引擎中的主流,也许现在已经是了。

个人其实也不算钻研,因为实际上 MathJax 很简单,调用 MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.element.nativeElement]); 就可以渲染一个元素(这个 this.element.nativeElement 是从 Angular 中调用它 DOM 的语法),这个 .Queue 实际上是 MathJax 自己实现的回调格式,语法非常清奇,参数个数不定,每个都是数组,代表一个回调,顺序执行。比如这个 ['Typeset', MathJax.Hub, this.element.nativeElement] ,第一个元素是方法名,第二个元素是 this ,之后的元素都是参数……

我们可以看到这个就相当于执行 MathJax.Hub.Typeset(this.element.nativeElement) ,那为啥不执行这个?因为这方法是同步的,会导致页面十分卡。于是 MathJax 就自己封装了一个异步队列(它的 API 可能几百年没改了)

我们说回 Angular。因为要用 markdown,我的思路是用 marked 封装一个 directive。那么我们就应该在 marked 渲染完成之后用 MathJax 去 Typeset 这个组件。但真的这样做了,却产生了奇妙的效果——切换页面之后,要等将近一分钟才开始渲染。我在它的队列里放了几个 log,发现每个元素都被 queue 了 4 次,几十个元素,难怪要一分钟才开始渲染下一页的内容,即使大部分 markdown 里面根本没有数学。

这时候我开始灰心了,这个问题就没有解决办法了吗?绝望之时,我想到能不能直接 Typeset document,结果是可以的,而且十分快。所以渲染并不慢,可能是渲染的初始化过程比较慢。那么这时候方案就出来了,我们可以尽量减少渲染次数,同时只渲染 document。只要这个渲染还在进行,那么有再多的元素 queue 上来,我们也只当作 queue 了一次。

于是我就写了这么个 service:

@Injectable()
export class MathjaxService {
 public isQueued = false;
 public isRunning = false;
 window: any;
 constructor(@Inject(PLATFORM_ID) private platformId: Object) {
 if (isPlatformBrowser(this.platformId)) {
 this.window = window as any;
 }
 }
 finishRunning() {
 this.isRunning = false;
 if (this.isQueued) {
 this.queueChange();
 }
 }
 queueChange() {
 if (this.isRunning) {
 this.isQueued = true;
 } else {
 this.isQueued = false;
 this.isRunning = true;
 if (isPlatformBrowser(this.platformId)) {
 if (this.window.MathJax) {
  this.window.MathJax.Hub.Config({
  messageStyle: 'none',
  tex2jax: {
  // preview: 'none',
  inlineMath: [['$', '$']],
  processEscapes: true
  }
  });
  this.window.MathJax.Hub.Queue(['log', console, 'start'], ['Typeset', this.window.MathJax.Hub, document], ['log', console, 'end'], ['finishRunning', this]);
 }
 } else {
 this.finishRunning();
 }
 }
 }
}

事实证明,它能圆满完成任务,它也就是现在运行在 这个网站 上的代码。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript 跨浏览器开发经验总结(五) js 事件
May 19 Javascript
js操作时间(年-月-日 时-分-秒 星期几)
Jun 20 Javascript
jquery ajax return没有返回值的解决方法
Oct 20 Javascript
Jquery选择子控件"大于号"和" "区别介绍及使用示例
Jun 25 Javascript
基于jquery的网站幻灯片切换效果焦点图代码
Sep 15 Javascript
理解 JavaScript Scoping & Hoisting(二)
Nov 18 Javascript
利用ES6实现单例模式及其应用详解
Dec 09 Javascript
jquery动态添加带有样式的HTML标签元素方法
Feb 24 jQuery
vue的mixins属性详解
Mar 14 Javascript
JavaScript实现拖拽效果
Mar 16 Javascript
微信小程序实现列表滚动头部吸顶的示例代码
Jul 12 Javascript
一文搞懂redux在react中的初步用法
Jun 09 Javascript
vue实现验证码输入框组件
Dec 14 #Javascript
基于滚动条位置判断的简单实例
Dec 14 #Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
Dec 14 #Javascript
ES6/JavaScript使用技巧分享
Dec 14 #Javascript
Django与Vue语法的冲突问题完美解决方法
Dec 14 #Javascript
浅析JS抽象工厂模式
Dec 14 #Javascript
JavaScript重复元素处理方法分析【统计个数、计算、去重复等】
Dec 14 #Javascript
You might like
php中最简单的字符串匹配算法
2014/12/16 PHP
PHP编写的图片验证码类文件分享
2016/06/06 PHP
php实现的redis缓存类定义与使用方法示例
2017/08/09 PHP
jQuery 表单验证扩展代码(二)
2010/10/20 Javascript
JS实现匀速运动的代码实例
2013/11/29 Javascript
js实现全屏漂浮广告移入光标停止移动
2013/12/02 Javascript
jquery无刷新验证邮箱地址实现实例
2014/02/19 Javascript
Angular中的Promise对象($q介绍)
2015/03/03 Javascript
基于replaceChild制作简单的吞噬特效
2015/09/21 Javascript
实例详解Nodejs 保存 payload 发送过来的文件
2016/01/14 NodeJs
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
学习掌握JavaScript中this的使用技巧
2016/08/29 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
vue的Virtual Dom实现snabbdom解密
2017/05/03 Javascript
vue以组件或者插件的形式实现throttle或者debounce
2019/05/22 Javascript
vue实现评论列表功能
2019/10/25 Javascript
[00:50]深扒TI7聊天轮盘语音出处6
2017/05/11 DOTA
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
tensorflow 实现打印pb模型的所有节点
2020/01/23 Python
PyCharm最新激活码PyCharm2020.2.3有效
2020/11/18 Python
Html5踩坑记之mandMobile使用小记
2020/04/02 HTML / CSS
Kate Spade美国官网:纽约新兴时尚品牌,以包包闻名于世
2017/11/09 全球购物
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
越南母婴用品购物网站:Kids Plaza
2020/04/09 全球购物
AJAX应用和传统Web应用有什么不同
2013/08/24 面试题
食品营养与检测应届生求职信
2013/11/08 职场文书
工艺工程师工作职责
2013/11/23 职场文书
毕业设计计划书
2014/01/09 职场文书
弘扬民族精神演讲稿
2014/05/07 职场文书
区域销售主管岗位职责
2014/06/15 职场文书
初中毕业生感言
2015/07/31 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
Win11 Build 21996.1 Dev版怎么样? win11系统截图欣赏
2021/11/21 数码科技
vue 给数组添加新对象并赋值
2022/04/20 Vue.js