You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:35:40