Youssef Maouche
Youssef Maouche

Reputation: 305

Event when typesetting is done MathJax 3

I'm using MathJax 3 to render math equations. The problem is that I need to add a click event to some symbols inside the math equation, so I use \cssId.


        loader: {
          load: ['[tex]/color','[tex]/cancel'],

        },

        tex: {
          packages: {'[+]': ['cancel']},
          inlineMath: [['$', '$'], ['\\(', '\\)']],
        },
    };
    </script>
    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
     <p id="demo">  ${x^2+4\cssId{someid}{x}+\sum_{s}}$ </p>
    <script>$("#someid").click(function () {
      some code ....
    })
  </script>

The click event not working because the id="" is not created yet. I tried to use the promises after the MathJax typeset like this.

<script>
$(document).ready(function () {
  MathJax.startup.promise.then(function () {
      $("#someid").click(function () {
  some code ....
})
  })
})

Uncaught TypeError: Cannot read property 'promise' of undefined

I tried also MathJax.typesetPromise(). It did not work either. Thanks in advance.

Upvotes: 4

Views: 3126

Answers (1)

Davide Cervone
Davide Cervone

Reputation: 12260

There are a couple of issues, here. First, because the MathJax script has the async property, you don't know when it will be processed, and it may be after your $(document).ready() call, as it appears to be in this case (since MathJax.startup isn't defined according to the error message). Second, $(document).ready() only means that the main document contents have been loaded, not that MathJax has finished its typesetting (or even begun it). In your case, you have asked for several TeX extensions to be loaded, and that causes MathJax to have to wait for those to arrive before beginning the typesetting. The $(document).ready() will run before those are loaded, and so before the typesetting occurs, and so before the element with someid is available.

In order to handle this properly, you need to use MathJax's ready functions instead.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script>
 MathJax = {
   loader: {
     load: ['[tex]/color','[tex]/cancel']
   },
   tex: {
     packages: {'[+]': ['cancel', 'color']},
     inlineMath: [['$', '$'], ['\\(', '\\)']]
   },
   startup: {
     pageReady() {
       return MathJax.startup.defaultPageReady().then(function () {
          $("#someid").click(function () {
            alert('clicked!');
          }).css('cursor', 'pointer');
       });
     }
   }
 };
</script>

<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

<p id="demo">  ${x^2+4\cssId{someid}{x}+\sum_{s}}$ </p>

Here we use the startup.pageReady() function to call the default page-ready function (which does the initial typesetting), and use the promise that it returns in order to add the click event handler. This makes sure the typesetting has occurred before doing so. I also added CSS to change the pointer when the mouse moves over the clickable math for a visual indication that clicking is possible.

Upvotes: 7

Related Questions