繼上一篇的數字公式 , 這次的功能是將公式能插入編輯器以及修改
1、Tinymce 自定義 LateX 按鈕,打開公式編輯器窗口 LateX.vue
window.tinymce.init({...//基礎配置這里我就不寫了setup(ed) {//自定義 LateX 按鈕ed.ui.registry.addButton('LateX', {text: 'LateX', // 按鈕文本onAction: function () {// 1. 獲取當前光標位置const latexEditorBookmark = ed.selection.getBookmark(2); // 獲取光標位置const editorId = ed.id; // 保存當前編輯器 IDconsole.log('activeEditorId:', editorId);// 2. 生成一個隨機的 ID,用于 wmath 標簽const uid = 'wmath-' + Math.random().toString(36).substr(2, 9);// 3. 創建一個 <wmath> 標簽并插入到光標處const wmathHtml = `<wmath contenteditable="false" data-id="${uid}" data-latex=""></wmath>`;ed.insertContent(wmathHtml); // 在光標位置插入 wmath 標簽// 4. 打開公式編輯器窗口,并傳遞光標位置、編輯器 ID 和 wmathIdconst url = `/LateX?editorId=${editorId}&wmathId=${uid}`;window.open(url, '_blank', 'width=1000,height=800,scrollbars=no,resizable=no');}});//點擊數字公式時打開窗口進行編輯var currentWmathElement = null;ed.on('click', function (e) {const wmathElement = e.target.closest('wmath');if (wmathElement) {currentWmathElement = wmathElement; // 👈 保存當前點擊的元素const latexContentRaw = wmathElement.getAttribute('data-latex') || '';console.log('at line 488: raw =', latexContentRaw);// 去除所有 $ 符號const latexContent = latexContentRaw.replace(/\$/g, '').trim();console.log('at line 489: cleaned =', latexContent);// 編碼后用于傳遞到彈窗const encoded = encodeURIComponent(latexContent);// 給 wmath 添加唯一 data-id,方便后續精準替換let wmathId = wmathElement.getAttribute('data-id');if (!wmathId) {wmathId = 'wmath-' + Math.random().toString(36).substr(2, 9);wmathElement.setAttribute('data-id', wmathId);}// 當前編輯器 ID 也保存下來(如果你有多個編輯器)const editorId = ed.id;// 打開編輯窗口并傳參(傳遞 data-id + 內容)window.open(`/LateX?id=${encoded}&wmathId=${wmathId}&editorId=${editorId}`,'_blank','width=1000,height=800,scrollbars=no,resizable=no');}});}})//監聽子頁面數據if (!window._wmath_listener_registered) {// 💾 新增公式插入點記錄let latexEditorBookmark = null;let activeEditorId = null;// 👂 message 監聽器:處理編輯 + 新增兩種情況window.addEventListener('message', function (event) {const data = event.data;console.log('data at line 648:', data);// ? 編輯現有公式:替換或刪除if (data && data.type === 'update-wmath') {const { editorId, wmathId, latex } = data;const newLatex = latex ? latex.trim() : '';if (!editorId || !wmathId) return;const targetEditor = tinymce.get(editorId);if (!targetEditor) return;const targetWmath = targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0];if (targetWmath) {if (!newLatex) {// ? 刪除公式targetEditor.dom.remove(targetWmath);} else {// ? 更新公式targetWmath.setAttribute('data-latex', newLatex);targetWmath.innerHTML = newLatex;setTimeout(() => {if (typeof renderMathJax === 'function') {this.window.renderMathJax(editorId);}}, 10);}}}});// 🚩 標記為已注冊,防止重復window._wmath_listener_registered = true;}
注意:所有的公式都是 $$ 公式 $$ 并且都是反斜杠
富文本存儲的時候 <wmath data-latex="$$ 公式 $$"> $$ 公式 $$ </wmath>
這里解釋一下為什么不直接存儲$$ 公式 $$
原因:
1、我們是用戶編輯內容,最終有后端形成word文件,編輯在進行處理,這就會導致不能隨意存儲數據
2、所有直接$$ 公式 $$ 渲染之后 會取代原內容 轉成這樣的標簽 并且不會記錄公式,所以我才想著在套一個自定義的標簽
3、為什么不能渲染的時候直接把公式賦值到父級span標簽上呢,由于原因1,我是不能存儲span 以及 p這種常規的標簽 如果把公式放到標簽上 也沒辦法保證用戶就只錄入一個公式 而且這種直接賦值也是js去渲染的比較慢
綜上所述還是自定義標簽比較好 ,

id是數字公式 wmathid 是 公式 唯一的id editorId則是編輯器的id 因為我會存在多個
