如何点击菜单按钮向Trix编辑器插入文本?含视频嵌入与模态框需求
解决Trix编辑器自定义视频插入按钮及相关问题
一、修正insertString使用问题,明确正确用法
你当前在textAttributes.parser里尝试插入内容的思路是错的——textAttributes是用来定义文本格式(如颜色、加粗)的配置项,根本不是用来处理自定义元素插入的。要实现内容插入,得在按钮的点击回调里操作编辑器实例。
获取编辑器实例的正确方式
可以通过Trix的trix-initialize事件提前保存当前编辑器实例,方便后续调用:
let trixEditorInstance; document.addEventListener("trix-initialize", function(event) { trixEditorInstance = event.target.editor; });
二、实现点击按钮弹出模态框输入URL
1. 先添加模态框的HTML结构
<!-- 视频插入模态框 --> <div id="videoModal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); padding:24px; background:#fff; border-radius:8px; box-shadow:0 2px 12px rgba(0,0,0,0.15); z-index:1000;"> <h3 style="margin-top:0; font-size:16px;">插入视频</h3> <label style="display:block; margin:12px 0 8px;">YouTube/Vimeo视频URL:</label> <input type="text" id="videoUrlInput" style="width:100%; padding:8px; border:1px solid #ddd; border-radius:4px;" placeholder="示例:https://www.youtube.com/watch?v=abc123"> <div style="display:flex; gap:8px; margin-top:16px; justify-content:flex-end;"> <button id="closeModalBtn" style="padding:8px 16px; border:1px solid #ddd; border-radius:4px; background:#fff; cursor:pointer;">取消</button> <button id="insertVideoBtn" style="padding:8px 16px; border:none; border-radius:4px; background:#007bff; color:#fff; cursor:pointer;">插入</button> </div> </div> <!-- 模态框遮罩层 --> <div id="modalOverlay" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:999;"></div>
2. 给Trix工具栏添加自定义按钮
通过trix-toolbar-initialize事件把按钮插入到工具栏:
document.addEventListener("trix-toolbar-initialize", function(event) { const toolbar = event.target; // 创建插入视频按钮 const videoBtn = document.createElement("button"); videoBtn.type = "button"; videoBtn.textContent = "插入视频"; videoBtn.classList.add("trix-button"); videoBtn.addEventListener("click", () => { // 打开模态框 document.getElementById("videoModal").style.display = "block"; document.getElementById("modalOverlay").style.display = "block"; document.getElementById("videoUrlInput").focus(); }); // 把按钮添加到文本工具组的后面 const textToolsGroup = toolbar.querySelector(".trix-button-group--text-tools"); textToolsGroup.insertAdjacentElement("afterend", videoBtn); });
3. 处理URL解析、ID加密及插入逻辑
// 从URL中提取YouTube/Vimeo视频ID function getVideoId(url) { let videoId = null; // 匹配YouTube的各种URL格式 const youtubeRegex = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/; const youtubeMatch = url.match(youtubeRegex); if (youtubeMatch) videoId = youtubeMatch[1]; // 匹配Vimeo的URL格式 const vimeoRegex = /vimeo\.com\/(\d+)/; const vimeoMatch = url.match(vimeoRegex); if (vimeoMatch) videoId = vimeoMatch[1]; return videoId; } // 视频ID加密函数(替换成你实际的加密逻辑) function encryptVideoId(id) { // 示例:用Base64简单编码,实际请用安全加密算法(如AES) return btoa(id); } // 插入视频元素到编辑器 document.getElementById("insertVideoBtn").addEventListener("click", function() { const input = document.getElementById("videoUrlInput"); const url = input.value.trim(); if (!url) return; const videoId = getVideoId(url); if (!videoId) { alert("请输入有效的YouTube或Vimeo视频URL"); return; } const encryptedId = encryptVideoId(videoId); // 创建自定义视频占位元素(可根据需求改成iframe或其他结构) const videoElement = document.createElement("div"); videoElement.className = "trix-video-embed"; videoElement.dataset.encryptedId = encryptedId; videoElement.style.padding = "12px"; videoElement.style.border = "1px dashed #ccc"; videoElement.style.borderRadius = "4px"; videoElement.innerHTML = `<p>已插入视频(加密ID:${encryptedId})</p>`; // 插入到编辑器当前光标位置 if (trixEditorInstance) { trixEditorInstance.focus(); trixEditorInstance.insertHTML(videoElement.outerHTML); } // 关闭模态框并清空输入 document.getElementById("videoModal").style.display = "none"; document.getElementById("modalOverlay").style.display = "none"; input.value = ""; }); // 关闭模态框 document.getElementById("closeModalBtn").addEventListener("click", function() { document.getElementById("videoModal").style.display = "none"; document.getElementById("modalOverlay").style.display = "none"; });
三、关键配置补充
Trix默认会过滤部分HTML元素和属性,要保留自定义的data-encrypted-id属性,需要添加如下配置:
// 允许自定义元素和属性 Trix.config.allowedElements.push("div"); Trix.config.allowedAttributes["data-encrypted-id"] = true;
内容的提问来源于stack exchange,提问作者Radek
相关产品推荐
相关产品推荐

