代码高亮块(Syntax-highlighted Code Block)
可复制代码片段(Copyable Code Snippet)
代码展示组件(Code Display Component)
1. 代码高亮块(Syntax-highlighted Code Block)特点:只做语法高亮,不提供复制按钮。
方案:用开源库 Prism.js 一键高亮。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>代码高亮块 - Prism.js</title>
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.css" rel="stylesheet" />
</head>
<body>
<pre><code class="language-js">
// 计算斐波那契数列
function fib(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
}
console.log(fib(10)); // 55
</code></pre>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.js"></script>
</body>
</html>
2. 可复制代码片段(Copyable Code Snippet)特点:功能单一,一个 <pre> + 复制按钮。
方案:原生按钮 + Clipboard API。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>可复制代码片段</title>
<style>
pre {
background:#1e1e1e;color:#d4d4d4;padding:1rem;border-radius:6px;position:relative;
white-space:pre-wrap;font-family:Consolas,Monaco,monospace;font-size:.9rem;
}
.copy-btn {
position:absolute;top:.5rem;right:.5rem;background:#3b82f6;color:#fff;border:none;
border-radius:4px;padding:.3rem .6rem;font-size:.75rem;cursor:pointer;
}
</style>
</head>
<body>
<pre id="myCode">
npm install vite --save-dev
</pre>
<button class="copy-btn">复制</button>
<script>
function copyCode() {
const text = document.getElementById('myCode').textContent;
navigator.clipboard.writeText(text).then(() => alert('已复制'));
}
</script>
</body>
</html>
3. 代码展示组件(Code Display Component)特点:标题 + 高亮 + 复制 + 状态反馈,完整组件。
方案:原生实现,可嵌入任何页面。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>代码展示组件</title>
<style>
.code-panel {max-width:720px;margin:2rem auto;font-family:-apple-system,BlinkMacSystemFont,sans-serif;}
.code-title {font-size:1.1rem;font-weight:600;margin-bottom:.5rem;}
.code-block {position:relative;background:#1e1e1e;color:#d4d4d4;border-radius:8px;padding:1rem 1.2rem;font-family:Consolas,Monaco,monospace;font-size:.9rem;overflow-x:auto;}
.copy-btn {position:absolute;top:.6rem;right:.6rem;background:#3b82f6;color:#fff;border:none;border-radius:4px;padding:.3rem .6rem;font-size:.75rem;cursor:pointer;}
.copy-btn.copied {background:#10b981;}
.msg {margin-top:.5rem;font-size:.8rem;color:#166534;display:none;}
</style>
</head>
<body>
<div class="code-panel">
<div class="code-title">React Hook 示例</div>
<div class="code-block" id="code">
<button class="copy-btn" id="copyBtn">复制</button>
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
</div>
<div class="msg" id="msg">复制成功!</div>
</div>
<script>
const btn = document.getElementById('copyBtn');
const code = document.getElementById('code');
const msg = document.getElementById('msg');
btn.addEventListener('click', async () => {
const text = code.cloneNode(true); // 深拷贝
text.querySelector('button').remove(); // 去掉按钮
await navigator.clipboard.writeText(text.textContent.trim());
btn.textContent = '已复制';
btn.classList.add('copied');
msg.style.display = 'block';
setTimeout(() => { btn.textContent = '复制'; btn.classList.remove('copied'); msg.style.display = 'none'; }, 2000);
});
</script>
</body>
</html>
<style>
.snippet {
position: relative;
background: #f5f5f5;
border-radius: 6px;
padding: 12px 40px 12px 12px;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 14px;
overflow-x: auto;
}
.snippet button {
position: absolute;
top: 6px;
right: 6px;
cursor: pointer;
background: #e0e0e0;
border: none;
border-radius: 4px;
padding: 2px 6px;
font-size: 12px;
}
</style>
<div class="snippet">
<button>Copy</button>
<code id="code">curl https://api.example.com/v1/status</code>
</div>
<script>
function copyCode(btn) {
const code = btn.nextElementSibling.innerText;
navigator.clipboard.writeText(code).then(() => {
btn.textContent = 'Copied';
setTimeout(() => (btn.textContent = 'Copy'), 1200);
});
}
</script>
|