调用Monaco的registerHoverProvider时能否为HoverProvider注入JS事件监听器
问题解答
调用registerHoverProvider时可以实现悬浮提示内容的自定义点击事件,直接写内联onclick属性不生效是因为Monaco的安全渲染策略会过滤内联脚本事件,可通过以下两种方案实现:
方案1:自定义协议+事件委托(更稳定,推荐)
- 步骤1:在悬浮内容的HTML中使用带自定义协议的
<a>标签,避免默认跳转行为 - 步骤2:全局绑定点击事件委托,捕获对应标签的点击事件执行自定义逻辑
// 1. 注册悬浮提供者 monaco.languages.registerHoverProvider('javascript', { provideHover: function (model, position) { return { range: new monaco.Range(1, 1, model.getLineCount(), model.getLineMaxColumn(model.getLineCount())), contents: [ { isTrusted: true, supportHtml: true, // 用自定义协议前缀标识需要触发自定义逻辑的链接 value: '<a href="my-custom://trigger-demo?data=test123">点击执行自定义代码</a>' } ] } } }) // 2. 全局绑定事件委托处理点击 document.addEventListener('click', function(e) { const target = e.target; // 判断是否是悬浮层内的自定义协议链接 if (target.tagName === 'A' && target.href.startsWith('my-custom://')) { e.preventDefault(); // 解析链接里的参数,执行业务逻辑 const url = new URL(target.href); const param = url.searchParams.get('data'); console.log('触发自定义逻辑,传入参数:', param); // 这里写你要执行的自定义代码 } })
方案2:监听悬浮显示事件直接绑定事件
- 步骤1:通过Monaco的
onDidShowHover事件监听悬浮层渲染完成的时机 - 步骤2:获取悬浮层DOM元素,直接给内部的交互元素绑定事件
// 注册悬浮提供者逻辑,HTML里给a标签加自定义类名便于查询 monaco.languages.registerHoverProvider('javascript', { provideHover: function (model, position) { return { range: new monaco.Range(1, 1, model.getLineCount(), model.getLineMaxColumn(model.getLineCount())), contents: [ { isTrusted: true, supportHtml: true, value: '<a class="custom-hover-link" data-param="test456">点击执行自定义代码</a>' } ] } } }) // 监听悬浮显示事件 monaco.editor.onDidShowHover(() => { // 查询所有悬浮层内的自定义链接 const links = document.querySelectorAll('.monaco-hover .custom-hover-link'); links.forEach(link => { // 避免重复绑定 if (link._hasBindEvent) return; link._hasBindEvent = true; link.addEventListener('click', () => { const param = link.dataset.param; console.log('触发自定义逻辑,传入参数:', param); // 执行业务代码 }) }) })
内容的提问来源于stack exchange,提问作者woodhead
相关产品推荐
相关产品推荐

