Font switching is not really a supposed use case, but it can be done. Here is a document that illustrates how:
<meta name="viewport" content="width=device-width">
<title>Switch Fonts</title>
async function setFont(select) {
const font = select.value;
MathJax.config.output.font = font;
const doc = MathJax.startup.document;
for (const name of Object.keys(doc.menu.jax)) {
if (!doc.menu.jax[name]) continue;
const jax = name.toLowerCase();
MathJax.config[jax].font = font;
promises.push(MathJax.loader.load(`[${font}]/${jax}`).then(() => {
const fontData = Object.values(MathJax._.output.fonts[font][`${jax}_ts`])[0];
MathJax.config[jax].dynamicPrefix = `[${font}]/${jax}/dynamic`;
MathJax.config[jax].fontData = fontData;
for (const extension of fontData.dynamicExtensions.keys()) {
MathJax._.output.fonts[extension]?.[jax]?.install?.();
const JAX = new doc.menu.jax[name].constructor(MathJax.config[jax]);
JAX.setAdaptor(doc.adaptor);
doc.menu.jax[name] = JAX;
await Promise.all(promises);
await doc.rerenderPromise(MathJax._.core.MathItem.STATE.METRICS);
If \(a \ne 0\), then \(ax^2 + bx + c = 0\) has two solutions,
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
<select id="font" onchange="setFont(this)">
<option>mathjax-asana</option>
<option>mathjax-bonum</option>
<option>mathjax-dejavu</option>
<option>mathjax-fira</option>
<option>mathjax-modern</option>
<option selected>mathjax-newcm</option>
<option>mathjax-pagella</option>
<option>mathjax-schola</option>
<option>mathjax-stix2</option>
<option>mathjax-termes</option>
<option>mathjax-tex</option>
document.querySelector('#font').value = 'mathjax-newcm';
I'm not going to go into the details of how this works, but in order to handle changing renderer as well as fonts, you need to deal with the potential of loading the font for both CHTML and SVG renderers. That way, if you switch renderers then switch fonts, then switch renders back to the original, the changed font will be used, not the font that previously in use with that renderer.
First, the font component is loaded, and then work done here to set up the output configurations properly for the font (usually handled by the output jax when its component is first loaded, but that won't occur a second time). Then a new instance of the output jax is created using the updated configuration and it is hooked into the menu cache. This is done for any output jax that have been loaded already. Finally, the new output jax used to replace the current one, and the document is re-rendered starting from the step that gets the metrics for the surroundings of the expressions on the page (as some of those depend on the font em- and ex-sizes, so need to be updated for the new font).
In any case, that's the basic idea. See if that works for you.
Davide