math-render.blade.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. @props(['content' => '', 'class' => '', 'inline' => false])
  2. <span class="math-render {{ $class }}">
  3. {!! $content !!}
  4. </span>
  5. @push('scripts')
  6. <!-- 引入 KaTeX 核心库 -->
  7. <script src="/js/katex.min.js?v={{ time() }}"></script>
  8. <!-- 引入 auto-render 扩展 (本地) -->
  9. <script src="/js/auto-render.min.js?v={{ time() }}"></script>
  10. <script>
  11. (function() {
  12. 'use strict';
  13. console.log('Math Render Script Loaded (Local Auto-Render)');
  14. // 配置项
  15. const renderOptions = {
  16. delimiters: [
  17. {left: '$$', right: '$$', display: true},
  18. {left: '$', right: '$', display: false},
  19. {left: '\\(', right: '\\)', display: false},
  20. {left: '\\[', right: '\\]', display: true}
  21. ],
  22. throwOnError: false,
  23. ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'option']
  24. };
  25. function renderAllMath() {
  26. if (typeof renderMathInElement === 'undefined') {
  27. console.warn('auto-render extension not loaded yet');
  28. return;
  29. }
  30. if (typeof window.katex === 'undefined') {
  31. console.warn('katex core not loaded yet');
  32. return;
  33. }
  34. console.log('Rendering math using auto-render...');
  35. // 1. 优先渲染 .math-render 元素 (通常是经过后端处理的)
  36. const elements = document.querySelectorAll('.math-render');
  37. elements.forEach(elem => {
  38. try {
  39. renderMathInElement(elem, renderOptions);
  40. elem.dataset.rendered = 'true';
  41. } catch (e) {
  42. console.error('Auto-render failed for element:', elem, e);
  43. }
  44. });
  45. // 2. 尝试渲染整个 body,以捕获未被包裹的公式
  46. // 使用较低的优先级或特定的容器如果可能
  47. try {
  48. renderMathInElement(document.body, renderOptions);
  49. } catch (e) {
  50. console.warn('Global auto-render warning:', e);
  51. }
  52. }
  53. // 初始化
  54. document.addEventListener('DOMContentLoaded', () => {
  55. // 稍微延迟以确保脚本执行顺序
  56. setTimeout(checkAndRender, 100);
  57. });
  58. function checkAndRender() {
  59. if (typeof window.katex !== 'undefined' && typeof renderMathInElement !== 'undefined') {
  60. console.log('KaTeX and auto-render loaded');
  61. initMathRenderer();
  62. } else {
  63. console.log('Waiting for KaTeX/auto-render...');
  64. setTimeout(checkAndRender, 100);
  65. }
  66. }
  67. function initMathRenderer() {
  68. renderAllMath();
  69. setupObservers();
  70. }
  71. function setupObservers() {
  72. const observer = new MutationObserver((mutations) => {
  73. let shouldRender = false;
  74. mutations.forEach((mutation) => {
  75. if (mutation.addedNodes.length > 0) {
  76. shouldRender = true;
  77. }
  78. });
  79. if (shouldRender) {
  80. if (window.mathRenderTimeout) clearTimeout(window.mathRenderTimeout);
  81. window.mathRenderTimeout = setTimeout(() => {
  82. console.log('DOM mutation detected');
  83. renderAllMath();
  84. }, 100);
  85. }
  86. });
  87. observer.observe(document.body, {
  88. childList: true,
  89. subtree: true
  90. });
  91. }
  92. // Livewire 兼容性
  93. document.addEventListener('livewire:initialized', () => {
  94. setTimeout(renderAllMath, 50);
  95. if (typeof Livewire !== 'undefined' && Livewire.hook) {
  96. Livewire.hook('morph.updated', ({ el, component }) => {
  97. renderAllMath();
  98. });
  99. Livewire.hook('commit', ({ component, commit, respond, succeed, fail }) => {
  100. succeed(({ snapshot, effect }) => {
  101. setTimeout(renderAllMath, 50);
  102. });
  103. });
  104. }
  105. });
  106. document.addEventListener('livewire:navigated', () => {
  107. setTimeout(renderAllMath, 50);
  108. });
  109. document.addEventListener('alpine:init', () => {
  110. setTimeout(renderAllMath, 50);
  111. });
  112. document.addEventListener('math:render', () => {
  113. renderAllMath();
  114. });
  115. })();
  116. </script>
  117. @endpush
  118. @push('styles')
  119. <link rel="stylesheet" href="/css/katex/katex.min.css">
  120. @endpush