بنقرة واحدة
wechat-html-paste
微信公众号 HTML 粘贴兼容性技术要点 — 确保复制的 HTML 粘贴到微信编辑器后样式完整保留
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
微信公众号 HTML 粘贴兼容性技术要点 — 确保复制的 HTML 粘贴到微信编辑器后样式完整保留
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
高德地图综合服务,支持POI搜索、路径规划、旅游规划、周边搜索和热力图数据可视化
Knowledge comic creator supporting multiple art styles and tones. Creates original educational comics with detailed panel layouts and sequential image generation. Use when user asks to create "知识漫画", "教育漫画", "biography comic", "tutorial comic", or "Logicomix-style comic".
Generate professional infographics with 21 layout types and 21 visual styles. Analyzes content, recommends layout×style combinations, and generates publication-ready infographics. Use when user asks to create "infographic", "visual summary", "信息图", "可视化", or "高密度信息大图".
Darwin Skill (达尔文.skill): autonomous skill optimizer inspired by Karpathy's autoresearch. Evaluates SKILL.md files using an 8-dimension rubric (structure + effectiveness), runs hill-climbing with git version control, validates improvements through test prompts, and generates visual result cards. Use when user mentions "优化skill", "skill评分", "自动优化", "auto optimize", "skill质量检查", "达尔文", "darwin", "帮我改改skill", "skill怎么样", "提升skill质量", "skill review", "skill打分".
从 DESIGN.md 生成预览图并截图的工作流 - 解决 Playwright 浏览器路径问题和 YAML 解析
Cron jobs auto-deliver final responses to configured targets — send_message to the same target gets deduplicated and skipped. Print report content directly as final response instead.
| name | wechat-html-paste |
| description | 微信公众号 HTML 粘贴兼容性技术要点 — 确保复制的 HTML 粘贴到微信编辑器后样式完整保留 |
| version | 1.0.0 |
| author | Hermes Agent |
| metadata | {"hermes":{"tags":["wechat","html","clipboard","css","compatibility"]}} |
微信公众号编辑器对粘贴的 HTML 有严格过滤,但 inline style 支持较完整。
| 方式 | MIME 类型 | 粘贴效果 | background-image |
|---|---|---|---|
writeText() | text/plain | ❌ 原始 HTML 代码 | 丢失 |
execCommand('copy') + hidden div | text/html | ✅ 渲染后富文本 | 可能丢失 |
ClipboardItem | text/html | ✅ 渲染后富文本 | ✅ 保留 |
// 粘贴后显示原始 HTML 代码字符串,完全不可用
navigator.clipboard.writeText(html);
// 用隐藏 div + selection 复制,MIME 是 text/html,粘贴为渲染内容
// 但浏览器序列化时可能丢弃 background-image 等 CSS 属性
const tempDiv = document.createElement('div');
tempDiv.innerHTML = fullHtml;
tempDiv.style.position = 'fixed';
tempDiv.style.left = '-9999px';
document.body.appendChild(tempDiv);
const range = document.createRange();
range.selectNodeContents(tempDiv);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
document.execCommand('copy');
selection.removeAllRanges();
document.body.removeChild(tempDiv);
// 直接写入 text/html MIME,保留 background-image 等完整 CSS
const blob = new Blob([html], { type: 'text/html' });
const item = new ClipboardItem({
'text/html': blob,
'text/plain': new Blob([html], { type: 'text/plain' })
});
navigator.clipboard.write([item]);
根因:writeText() 写入的是 text/plain,粘贴为纯文本。execCommand 通过 selection 复制,MIME 是 text/html 但浏览器序列化时会丢弃 background-image 等 CSS。ClipboardItem 直接写入 text/html MIME,保留完整 HTML。
实际建议:ClipboardItem 为主,execCommand 做 fallback。writeText() 绝对不要用于 HTML 内容。
微信会剥掉 <style> 标签,所有样式必须写在元素的 style 属性里:
<!-- ✅ 正确 -->
<section style="background-image: linear-gradient(...); padding: 20px;">
<h1 style="color: red;">标题</h1>
</section>
<!-- ❌ 错误 — <style> 会被剥掉 -->
<style>h1 { color: red; }</style>
<h1>标题</h1>
| 属性 | 支持 |
|---|---|
background-image: linear-gradient(...) | ✅ |
background-color | ✅ |
background-size, background-repeat | ✅ |
color, font-size, font-weight | ✅ |
margin, padding, border, border-radius | ✅ |
box-shadow | ✅ |
position: absolute/fixed | ❌ |
transform, animation | ❌ |
<svg> 内联元素 | ❌(会被剥掉) |
<style> 标签 | ❌(会被剥掉) |
参考 xhs.pro 的实现:
const fullHtml = `<section style="font-family: ...; line-height: 1.75; font-size: 16px; background-image: linear-gradient(...); background-size: 20px 20px; padding: 20px;">
<!-- 正文内容,所有样式已 inline -->
<h1 style="...">标题</h1>
<p style="...">内容</p>
</section>`;
属性顺序很重要:background(简写)必须在 background-image 之前,否则简写会覆盖具体属性。
const wenyanMatch = themeCss.match(/#wenyan\\s*\\{([^}]*)\\}/);
if (wenyanMatch) {
const block = wenyanMatch[1];
// ⚠️ 顺序: shorthand 在前,specific 在后
const bgProps = ['background', 'background-color', 'background-image',
'background-size', 'background-repeat', 'background-position',
'background-attachment', 'padding'];
for (const prop of bgProps) {
const re = new RegExp(prop + '\\\\s*:\\\\s*([^;]+);');
const m = block.match(re);
if (m) bgInline += prop + ':' + m[1].trim() + ';';
}
}
function copyHtml() {
const html = document.getElementById('wenyan').innerHTML;
const themeCss = getThemeCss(); // 从主题 CSS 获取
// 1. 提取背景属性到 inline style
let bgInline = '';
const wenyanMatch = themeCss.match(/#wenyan\\s*\\{([^}]*)\\}/);
if (wenyanMatch) {
const block = wenyanMatch[1];
const bgProps = ['background', 'background-color', 'background-image',
'background-size', 'background-repeat', 'background-position',
'background-attachment', 'padding'];
for (const prop of bgProps) {
const re = new RegExp(prop + '\\\\s*:\\\\s*([^;]+);');
const m = block.match(re);
if (m) bgInline += prop + ':' + m[1].trim() + ';';
}
}
// 2. 用 <section> 包裹(和 xhs.pro 一样),不带 <style> 标签
const fullHtml = `<section style="font-family: ...; line-height: 1.75; font-size: 16px;${bgInline}">
${html}
</section>`;
// 3. ClipboardItem 为主,execCommand 为 fallback
const blob = new Blob([fullHtml], { type: 'text/html' });
const item = new ClipboardItem({
'text/html': blob,
'text/plain': new Blob([fullHtml], { type: 'text/plain' })
});
navigator.clipboard.write([item]).catch(() => {
// fallback: selection + execCommand(会丢 background-image)
});
}
微信公众号中实现网格纸效果,必须用双层 linear-gradient,不能用 repeating-linear-gradient(微信不支持)。
#wenyan {
background-color: #ffffff;
background-image:
linear-gradient(rgba(200, 200, 200, 0.25) 1px, transparent 1px),
linear-gradient(90deg, rgba(200, 200, 200, 0.25) 1px, transparent 1px);
background-size: 20px 20px;
}
transparent 1px 为间距)90deg)rgba(200,200,200,0.25) 控制网格线颜色深浅,0.25 为淡灰色20px 20px 控制网格间距rgba(87, 107, 149, 0.15) 蓝灰色调navigator.clipboard.read() 需要页面处于焦点状态。DevTools 控制台打开时焦点在控制台而非页面,会导致 NotAllowedError。
解决:先用鼠标点击页面区域让其获得焦点,再在控制台执行代码。
用 F12 拦截目标工具的剪贴板输出,确认其实现方式:
// 覆盖 navigator.clipboard.write 拦截复制内容
const orig = navigator.clipboard.write.bind(navigator.clipboard);
navigator.clipboard.write = function(items) {
return orig(items).then(() => {
items[0].getType('text/html').then(blob => blob.text().then(t => {
console.log('COPIED HTML:', t);
}));
});
};
console.log('Interceptor ready — now click copy');
<style> 标签会被剥掉position: absolute/fixed 不支持transform、animation 不支持px