把 CodeMirror 中链接变为可点击(Clickable Link)
2021/4/8 18:29:49
本文主要是介绍把 CodeMirror 中链接变为可点击(Clickable Link),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
问题
很多编辑器,比如 VSCode 都可以自动检测文本中的链接,然后点击链接就可以打开网页。
但是 CodeMirror(一个基于 Web 的编辑器,CodePen 用的就是这个)没有自带这个功能,所以需要手动添加。
添加后的效果:
解决
方法 1(推荐)
利用 cm.eachLine
对每一行进行遍历,用正则表达式判断其中的链接,并用 cm.markText
给链接文本添加 className,
之后再监听点击事件,判断点击的元素的 className,根据按键类别打开链接。
// editor 就是 CodeMirror 的实例,也就是上面说的 cm const urlRegex = /(https?):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g editor.eachLine(line => { const result = line.text.match(urlRegex)?.[0] if (result) { const posLine = editor.lineInfo(line).line // 链接的行号 const posStart = line.text.indexOf(result) // 链接的起始字符位置 const posEnd = posStart + result.length // 结束字符位置 editor.markText( { line: posLine, ch: posStart }, { line: posLine, ch: posEnd }, { className: 'cm-clickable-link', // 也可以直接替换文本,https://codemirror.net/doc/manual.html#markText } ) } }) editor.on('mousedown', (_cm, event) => { // 1 = 鼠标左键,2 = 鼠标右键,4 = 鼠标中键 if (event.buttons === 1 || event.buttons === 4) { const element = event.target as Element if (element.classList.contains('cm-clickable-link')) { // 打开链接 ... } } })
方法 2
在 cm.renderLine
中直接添加包含链接的元素的 className,这种方法的缺点是包含链接的元素中可能不止含有链接,比如还有引号之类的。
下面是我参考的一个开源项目 tulios/json-viewer 的效果,后面的代码也是我根据他改编的。
editor.on('renderLine', (cm, line, element) => { // 选择一行中所有的 `.cm-string`,这里对应的是 JSON 中的 `值`,可以根据自己的需求改 const nodes = element.querySelectorAll('.cm-string') if (nodes && nodes.length > 0) { // 对于每一个 `.cm-string` 执行 ... nodes.forEach(node => { if (node) { const result = node.textContent?.match(urlRegex)?.[0] if (result) { node.classList.add('cm-clickable-link') node.setAttribute('url', result) } } }) } }) // 后面和 方法 1 中的监听 mousedown 相同
方法 3
针对 方法 2 中的缺点,还有一种解决方法就是直接替换 node
为 HTML,
但这种方法也有缺点,就是修改后的链接无法被选中,而且在某些时候会消失,性能也不好。
editor.on('renderLine', (cm, line, element) => { const nodes = element.querySelectorAll('span') if (nodes && nodes.length > 0) { nodes.forEach(node => { if (node) { const result = node.textContent?.match(urlRegex)?.[0] if (result) { // node.classList.add('cm-clickable-link') // node.setAttribute('url', result) // 替换成: node.innerHTML = node.innerHTML.replace( result, `<span data-url="${result}" class="cm-string cm-clickable-link">${result}</span>` ) } } }) } })
这篇关于把 CodeMirror 中链接变为可点击(Clickable Link)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升