| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /**
- * 数学公式渲染系统 - 全局配置
- * 适用于 Laravel + Livewire + Filament
- */
- (function() {
- 'use strict';
- // 全局配置
- window.MathRenderConfig = {
- attempts: 0,
- maxAttempts: 50,
- delay: 100,
- selector: '.math-text',
- autoInit: true
- };
- // 渲染单个数学元素
- window.renderMathElement = function(element) {
- if (!element) return;
- // 避免重复渲染
- if (element.dataset.rendered === 'true') {
- return;
- }
- // 确保 KaTeX 已加载
- if (typeof window.katex === 'undefined') {
- if (window.MathRenderConfig.attempts < window.MathRenderConfig.maxAttempts) {
- window.MathRenderConfig.attempts++;
- setTimeout(() => {
- window.renderMathElement(element);
- }, window.MathRenderConfig.delay);
- }
- return;
- }
- try {
- const content = element.dataset.mathContent || element.textContent;
- if (!content) return;
- let html = content;
- // 渲染 $$...$$ 块级公式
- html = html.replace(/\$\$([\s\S]*?)\$\$/g, (match, formula) => {
- try {
- return window.katex.renderToString(formula.trim(), {
- throwOnError: false,
- displayMode: true
- });
- } catch (e) {
- console.warn('[KaTeX] Render error for block formula:', e);
- return match;
- }
- });
- // 渲染 \[...\] 块级公式
- html = html.replace(/\\\[([\s\S]*?)\\\]/g, (match, formula) => {
- try {
- return window.katex.renderToString(formula.trim(), {
- throwOnError: false,
- displayMode: true
- });
- } catch (e) {
- console.warn('[KaTeX] Render error for block formula:', e);
- return match;
- }
- });
- // 渲染 $...$ 行内公式
- html = html.replace(/\$(.*?)\$/g, (match, formula) => {
- try {
- return window.katex.renderToString(formula, {
- throwOnError: false,
- displayMode: false
- });
- } catch (e) {
- console.warn('[KaTeX] Render error for inline formula:', e);
- return match;
- }
- });
- // 渲染 \(...\) 行内公式
- html = html.replace(/\\\((.*?)\\\)/g, (match, formula) => {
- try {
- return window.katex.renderToString(formula, {
- throwOnError: false,
- displayMode: false
- });
- } catch (e) {
- console.warn('[KaTeX] Render error for inline formula:', e);
- return match;
- }
- });
- element.innerHTML = html;
- element.dataset.rendered = 'true';
- } catch (error) {
- console.error('[KaTeX] Render error:', error);
- }
- };
- // 渲染所有数学元素
- window.renderAllMath = function() {
- document.querySelectorAll(window.MathRenderConfig.selector).forEach(window.renderMathElement);
- window.MathRenderConfig.attempts = 0;
- };
- // 手动触发渲染
- window.triggerMathRender = function() {
- window.renderAllMath();
- };
- // DOM 加载完成初始化
- function init() {
- if (!window.MathRenderConfig.autoInit) {
- return;
- }
- // 加载 KaTeX(如果尚未加载)
- if (typeof window.katex === 'undefined') {
- const script = document.createElement('script');
- script.src = '/js/katex.min.js';
- script.defer = true;
- script.onload = () => {
- console.log('[KaTeX] Loaded successfully');
- window.renderAllMath();
- };
- script.onerror = () => {
- console.error('[KaTeX] Failed to load');
- };
- document.head.appendChild(script);
- } else {
- window.renderAllMath();
- }
- }
- // 事件监听器
- document.addEventListener('DOMContentLoaded', init);
- // Livewire 事件
- document.addEventListener('livewire:initialized', () => {
- console.log('[MathRender] Livewire initialized');
- window.renderAllMath();
- });
- document.addEventListener('livewire:navigated', () => {
- console.log('[MathRender] Livewire navigated');
- setTimeout(window.renderAllMath, 100);
- });
- document.addEventListener('livewire:updated', () => {
- console.log('[MathRender] Livewire updated');
- setTimeout(window.renderAllMath, 100);
- });
- // Alpine.js 事件
- document.addEventListener('alpine:init', () => {
- console.log('[MathRender] Alpine initialized');
- window.renderAllMath();
- });
- // 自定义事件
- document.addEventListener('math:render', window.renderAllMath);
- document.addEventListener('math:render:force', () => {
- document.querySelectorAll(window.MathRenderConfig.selector).forEach(el => {
- delete el.dataset.rendered;
- });
- window.renderAllMath();
- });
- // 表单验证后渲染
- document.addEventListener('filament:form:validated', window.renderAllMath);
- // 全局暴露
- window.MathRender = {
- render: window.renderMathElement,
- renderAll: window.renderAllMath,
- trigger: window.triggerMathRender,
- config: window.MathRenderConfig
- };
- console.log('[MathRender] System initialized');
- })();
|