按需加载 MathJax(自动渲染数学公式)

仅在检测到页面中存在数学公式时才加载 MathJax 并进行渲染。

// ==UserScript==
// @name         按需加载 MathJax(自动渲染数学公式)
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  仅在检测到页面中存在数学公式时才加载 MathJax 并进行渲染。
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';
    /* global MathJax */
    // 如果已经加载 MathJax,则跳过
    if (typeof MathJax !== 'undefined') {
        console.log('MathJax 已经加载,跳过重复加载。');
        return;
    }

    // 检测页面中是否包含数学公式
    function hasMathContent() {
        // 1. 检查是否存在 MathJax 公式脚本
        if (document.querySelector('script[type="math/tex"], script[type="math/tex; mode=display"]')) {
            return true;
        }

        // 2. 检查文本中是否包含公式定界符
        const skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'PRE', 'TEXTAREA', 'CODE'];
        const mathPattern = /(^|[^\\])\$(\$?[\s\S]*?\$?)\$(?![^\s])/;

        const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
            acceptNode: function(node) {
                const parentTag = node.parentNode ? node.parentNode.nodeName.toUpperCase() : '';
                if (skipTags.includes(parentTag)) {
                    return NodeFilter.FILTER_SKIP;
                }
                return NodeFilter.FILTER_ACCEPT;
            }
        });

        while (walker.nextNode()) {
            const text = walker.currentNode.textContent;
            if (mathPattern.test(text)) {
                return true;
            }
        }

        return false;
    }

    // 异步检测,避免阻塞页面
    setTimeout(() => {
        if (!hasMathContent()) {
            console.log('未检测到数学公式,不加载 MathJax。');
            return;
        }

        // 配置 MathJax
        window.MathJax = {
            tex: {
                inlineMath: [['$', '$']],
                displayMath: [['$$', '$$']]
            },
            options: {
                skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
                ignoreHtmlClass: 'tex2jax_ignore'
            }
        };

        // 动态加载 MathJax
        const script = document.createElement('script');
        script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
        script.async = true;

        script.onload = function () {
            console.log('MathJax 加载完成,开始渲染数学公式...');
            MathJax.typesetPromise().catch(err => console.error('MathJax 渲染失败:', err));
        };

        script.onerror = function () {
            console.error('MathJax 加载失败,请检查网络连接或 CDN 地址。');
            alert('数学公式渲染失败:无法加载 MathJax,请检查网络连接。');
        };

        document.head.appendChild(script);
    }, 0);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址