如何在Docusaurus的代码块中添加自定义按钮并绑定点击事件?
在Docusaurus中为代码块添加自定义按钮并绑定事件
以下是适配Docusaurus React渲染机制的具体实现方案,替代纯DOM操作的不稳定方式:
1. 让代码块支持自定义属性标记
Docusaurus基于markdown-it解析Markdown,我们可以通过markdown-it-attrs插件实现类似Eleventy中{edit=yes}的属性标记功能:
- 安装依赖:
npm install markdown-it-attrs --save-dev
- 在
docusaurus.config.js中配置markdown插件:
module.exports = { presets: [ [ '@docusaurus/preset-classic', { docs: { markdownPlugins: [ require('markdown-it-attrs'), ], }, // 保留项目原有配置 }, ], ], };
2. 自定义CodeBlock组件(核心步骤)
Docusaurus支持通过主题组件覆盖机制替换默认代码块组件,在React层面控制按钮渲染和事件绑定,避免DOM操作的时序问题:
- 在项目根目录创建
src/theme/CodeBlock.js文件(无src/theme目录则新建),内容如下:
import React from 'react'; import CodeBlock from '@theme/CodeBlock'; export default function CustomCodeBlock({children, metastring, ...props}) { // 解析代码块后的属性字符串,比如{edit=yes} const blockAttrs = {}; if (metastring) { const attrMatch = metastring.match(/\{([^}]+)\}/); if (attrMatch) { attrMatch[1].split(',').forEach(item => { const [key, value] = item.trim().split('='); blockAttrs[key] = value || true; }); } } // 绑定打开Plnkr的点击事件 const openInPlnkr = () => { const codeContent = children.trim(); // 这里替换为实际的Plnkr代码提交逻辑 // 示例:打开Plnkr编辑器(可按需构造带代码的URL或通过表单提交) const plnkrUrl = 'https://plnkr.co/edit/?p=preview'; window.open(plnkrUrl, '_blank'); }; return ( <div style={{position: 'relative', marginBottom: '16px'}}> {/* 根据属性判断是否显示编辑按钮 */} {blockAttrs.edit && ( <button onClick={openInPlnkr} style={{ position: 'absolute', top: '8px', right: '8px', padding: '4px 10px', backgroundColor: '#2563eb', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', fontSize: '12px', zIndex: 10, }} > Edit in Plnkr </button> )} {/* 渲染原有的代码块 */} <CodeBlock {...props}> {children} </CodeBlock> </div> ); }
3. 在Markdown/MDX中使用
现在可以在代码块后添加属性标记,控制按钮显示:
function greet() { console.log('Hello Docusaurus!'); }
扩展:添加多个功能按钮
若需要多个按钮,只需扩展属性和组件逻辑:
- Markdown中:
// 示例代码
- 在
CustomCodeBlock中添加下载按钮逻辑:
// ... 原有代码 const downloadCode = () => { const blob = new Blob([children.trim()], {type: 'text/javascript'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'sample-code.js'; a.click(); URL.revokeObjectURL(url); }; // ... 在return中添加下载按钮 {blockAttrs.download && ( <button onClick={downloadCode} style={{ position: 'absolute', top: '8px', right: '80px', padding: '4px 10px', backgroundColor: '#16a34a', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', fontSize: '12px', zIndex: 10, }} > Download </button> )}
内容的提问来源于stack exchange,提问作者Jor
相关产品推荐
相关产品推荐

