如何实现类GitHub标记转换器,监听回车自动将[text|link]转为a标签
回车自动转换链接标记语法实现方案
核心实现思路
- 监听可编辑区域的
keydown事件,检测到回车键触发后执行解析逻辑 - 阻止默认回车换行行为,避免出现多余空行
- 获取当前光标所在行的全部文本内容,匹配
[text|link]格式的标记片段 - 解析出链接文本和地址后替换为标准a标签,更新当前行的内容
- 末尾自动插入新行并将光标定位到新行开头,不影响后续正常输入
效果参考

可直接使用的代码
// 和你原有代码的变量保持对齐,innerDoc就是你之前用的timeline.contentDocument innerDoc.addEventListener('keydown', function(e) { // 仅监听回车键 if (e.key !== 'Enter') return; e.preventDefault(); // 获取当前光标选区 const selection = timeline.contentWindow.getSelection(); const range = selection.getRangeAt(0); // 定位当前输入行的父元素 let currentLine = range.commonAncestorContainer; if (currentLine.nodeType === Node.TEXT_NODE) { currentLine = currentLine.parentElement; } // 匹配标记语法,修复原有正则的贪婪匹配问题 const lineContent = currentLine.textContent; const linkRegex = /\[([^|]+)\|([^\]]+)\]/g; let hasMatched = false; const replacedHtml = lineContent.replace(linkRegex, (_, text, link) => { hasMatched = true; return `<a href="${link.trim()}" target="_blank">${text.trim()}</a>`; }); // 存在匹配项时更新当前行内容 if (hasMatched) { currentLine.innerHTML = replacedHtml; } // 插入新行,适配不同编辑器的换行标签,用p就改p,用div就改div const newLine = document.createElement('div'); newLine.innerHTML = '<br>'; currentLine.after(newLine); // 光标移动到新行开头 const newRange = document.createRange(); newRange.setStart(newLine, 0); newRange.collapse(true); selection.removeAllRanges(); selection.addRange(newRange); });
适配说明
- 如果你使用的编辑器框架对换行有自定义处理,调整新行创建的标签类型即可
- 可额外增加链接合法性校验逻辑,过滤无效的url地址
- 若需要支持一行内多个链接标记同时转换,上述正则已支持全局匹配,无需额外修改
内容的提问来源于stack exchange,提问作者Avinash Pathak
相关产品推荐
相关产品推荐

