轻量级前端插件ponytail:长文本截断与展开交互实践
我一度很抵触在项目里做“长文本截断”这种需求。倒不是不会写而是它表面看起来三五行 CSS 就能解决真正上线后却被产品、UI、测试轮番提问题为什么这段只截了两行为什么展开之后按钮位置跳了为什么复制全文时选区老是不对后来我把整套逻辑从业务里抽出来做成一个使用起来非常轻量的插件起了个名字叫ponytail才总算把这类需求统一处理干净。这篇东西算是我自己对这个插件的使用笔记也把安装、配置和踩过的坑一起整理出来希望给正在做类似功能的人一点参考。ponytail 是一个专注于“文本折叠 / 展开”的轻量级 JavaScript 插件压缩后大约 2KB零依赖。它解决的问题很具体当一段文本超过指定行数时自动折叠成 N 行并露出一个“展开”按钮点击后收起状态变成完整内容再次点击恢复折叠。它不像 UI 框架里的复杂组件那样厚重也不像手写 CSS 截断那样没法自带交互。无论你是写博客列表、后台表格、移动端卡片还是商品详情页都可以直接拿它来处理摘要文本。如果你是刚接触前端的新手或者已经在业务里被各种“截断 展开”的边角问题折磨过这篇文章应该都适用。我会先讲清楚为什么自己做这个插件再给完整的最小使用示例然后展开配置项、实战踩坑和几个高频进阶用法。1. 为什么需要 ponytail一个截断插件要解决的真实痛点很多需求看起来简单做起来才发现全是细节。长文本截断就是典型例子。如果只要求“显示不满两行多出的打省略号”CSS 能轻松应付但一旦要加上“展开 / 收起”的交互纯 CSS 就无法闭环了。1.1 CSS 原生截断的三种方案与局限先说单行截断这是最古老的方案.truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }这组样式在任何现代浏览器都表现稳定缺点也明显只能限制单行。如果你需要两行、三行甚至动态行数它直接出局。而且它只是“视觉截断”文本对象其实依然完整地在文档流里复制时会把整段都选走屏幕上却只看到一行产品看到这种状态经常会问“怎么复制的和显示不一致”。然后是-webkit-line-clamp多行截断.clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }这组代码在现在的 Chromium、Firefox、Safari 里已经可以统一使用算是不错的基础方案。但它依然不解决“展开”交互你截断后没有按钮没有状态也没有动画。想要做“点击展开全部、再点击收起”必须额外写一套 JS 去切换类名、控制高度。更麻烦的是-webkit-line-clamp是一个偏展示层的属性你很难精确知道“最后一行最后一个可见字符”在哪也就没法在省略号旁边放一个对齐准确的按钮。还有一批团队选择用 JS 手动测量文本高度。思路通常是把目标元素的clientHeight与lineHeight * maxLines比较如果内容超高就通过二分查找逐个字符地试找到能够放下的最大字符数再在末尾插入省略号。这个方案能精细控制但它需要处理字体加载、容器 resize、选区复制、极端字符如 emoji换行等一堆边界情况代码写出来轻则几十行重则上百行。更要命的是这类算法很难做到跨项目复用——今天这个页面的文案逻辑是这个明天另一个页面又不一样最后往往变成“每个页面一套截断代码”。1.2 ponytail 的定位把“截断 展开”收敛成一个通用动作我当初决定做 ponytail本质上就是想把上面这些散落在各个业务里的逻辑收敛成一句话把超过 N 行的文本扎成 N 行留一条可点击的“小尾巴”。名字就来自马尾辫长发收束成马尾展开按钮就是那个发圈。ponytail 的核心设计有这么几条零依赖实现。不引 jQuery不依赖任何框架。原生 JavaScript 写好 UMD 包浏览器直接script引入能用Webpack / Vite 项目import也能用。不干扰原始文本。插件会复制需要展示的文本内容配合高度截断来渲染原始完整文本保存在>npm install ponytail然后在代码里引入import Ponytail from ponytail;如果是写 Demo、静态页面不想走构建工具可以直接用 CDNscript srchttps://unpkg.com/ponytaillatest/dist/ponytail.min.js/script加载后全局会挂载window.Ponytail直接使用即可。还有一种更可控的方式从项目的dist目录里把ponytail.min.js下载到本地放到自己的libs目录。我个人比较推荐这种因为团队项目往往需要锁版本不能直接依赖 CDN 上随时浮动的latest。而且这个插件真的很小本地放一份完全没有负担。2.2 一个最小可运行示例假设页面上有这样一个结构div classnews-card p idsummary这是一段很长的新闻摘要……省略几百字……以上就是摘要内容。/p /div只需要这样初始化const summary document.getElementById(summary); const instance new Ponytail(summary, { maxLines: 3 });运行后如果文本超过 3 行插件会在末尾自动生成一个“展开”按钮如果没有超过 3 行页面不会出现任何多余元素。点击“展开”后按钮文案会变成“收起”再点击一次回到折叠状态。它内部做了一件关键事先读取元素的line-height和当前宽度算出 “N 行文本” 对应的最大高度lineHeight * maxLines再把内容放进一个容器里设置max-height与overflow: hidden。按钮并不是插在文本末端而是通过绝对定位悬浮在容器的右下角这样即使中文省略号位置有偏差也不影响点击区域。为什么不用现成的-webkit-line-clamp我在实际封装时对比过line-clamp对“纯展示”确实好用但它把截断线画死了想在这个截断位置叠加一个与文字同行对齐的按钮很麻烦。而固定max-height的方案能更自由地控制按钮位置展开和收起的过渡动画也更好写。代价是需要在初始化时多算一次高度但这个计算成本可忽略。2.3 属性式自动初始化静态页面也能用如果你不想在 HTML 里写大量 JavaScript可以利用>p >Ponytail.init();init()会扫描所有带>document.addEventListener(DOMContentLoaded, function () { Ponytail.init(); });如果你用的是打包器脚本本身经过模块加载通常已经在 DOM 解析之后执行可以放心直接调用。3. 参数与行为配置从默认值到定制化ponytail 的 API 我尽量做得扁平。不搞几十个参数但常用的定制项一个都不少。下面这张表格是我自己的速查表。3.1 核心配置项速查配置项类型默认值说明maxLinesnumber3折叠时最多显示的行数expandTextstring展开展开按钮的文案collapseTextstring收起收起按钮的文案autoCollapsebooleanfalse展开后点击别处是否自动收起durationnumber200展开收起动画时长单位 msbuttonClassstring追加到按钮上的自定义类名ellipsisbooleantrue是否在折叠区域右下角追加省略号ellipsisSymbolstring…省略号字符preserveTextbooleantrue是否保留原始完整文本到>.ponytail-btn::after { content: ▾; }autoCollapse在移动端很实用。展开一个卡片后用户如果想继续浏览其他列表点击空白区域自动收起体验会比必须再点一次“收起”更自然。3.2 回调事件onExpand 和 onCollapse 能做什么插件提供了两种全局回调可以在初始化时传入new Ponytail(document.querySelector(.summary), { maxLines: 3, onExpand: function (el, info) { console.log(展开, el, info); }, onCollapse: function (el, info) { console.log(收起, el, info); } });这里el是触发回调的目标元素info里包含instance、isExpanded、prevHeight等状态信息。实际项目里我经常用onExpand做埋点比如统计用户展开次数或者在手风琴布局中收起其他项。手风琴场景的写法类似这样document.querySelectorAll(.summary).forEach((el) { new Ponytail(el, { onExpand: function (currentEl) { document.querySelectorAll(.summary).forEach((otherEl) { if (otherEl ! currentEl) { const inst otherEl.__ponytail_instance; if (inst inst.isExpanded) inst.collapse(); } }); } }); });3.3 通过 CSS 变量定制主题我刻意不让插件直接接管按钮的字体颜色、背景色等视觉属性而是把它做成一套语义化的 CSS 变量默认值保守方便业务层覆盖.ponytail-wrap { --ponytail-color: #1677ff; --ponytail-bg: transparent; --ponytail-font-size: inherit; } .ponytail-btn { color: var(--ponytail-color); background: var(--ponytail-bg); font-size: var(--ponytail-font-size); }这样做的原因是按钮的样式跟业务主题强相关让 JS 去逐个设置style.color会产生大量重复的重排操作。用 CSS 变量以后暗色模式切换、品牌色变更都只需要覆盖一层变量完全不用动 JS。4. 实战中的踩坑与排查插件写起来不难真正考验人的是各种环境差异和交互细节。下面这几个坑都是我在真实业务里踩过的也是一旦踩上就很难查的问题。4.1 折叠高度计算不准字体加载导致断行错误这个坑我印象最深。页面使用了网页字体比如思源黑体HTML 解析后立刻调用Ponytail.init()结果大量文本出现“短内容被折叠、长内容没折叠”的错乱。排查链路是这样的先在 Chrome DevTools 里打印元素的scrollHeight和clientHeight发现两者居然一样理论上不会折叠。但视觉上明明已经出现省略号。后来我意识到控制台打开时字体已经加载完成浏览器基于新字体重新刷新了布局我之前看到的“一致”是字体加载后重新计算的结果并非初始化时刻的真实状态。也就是说问题出在初始化时机太早字体没就绪时插件用后备字体计算了行高换行位置完全不同得到的高度结论自然无效。解决方法是等字体加载完成后初始化if (document.fonts document.fonts.ready) { document.fonts.ready.then(() Ponytail.init()); } else { window.addEventListener(load, () Ponytail.init()); }如果是业务中的单个实例也可以把new Ponytail(...)放到window.load事件回调中。这个坑告诉我所有涉及文本测量的插件都必须考虑字体加载时间。宁可让页面多显示几百毫秒的完整文本也不要截出错误结果。4.2 点击与拖拽的冲突想复制文本却误触发展开有个用户反馈他想复制折叠文本的一部分鼠标从文本上划过去再松开页面却直接展开成了全文。起初我怀疑是事件委托把 click 冒泡到了按钮上仔细排查后发现这是浏览器原生 click 行为和文本选区的经典冲突。当mouseup发生时如果鼠标最终停在一个按钮上浏览器仍然会派发一次click事件到按钮上。用户拖动选择文本时目标位置很容易落在“展开”按钮上于是按钮被点开选区也乱了。我的修复策略有两层。第一层在按钮的click回调中判断当前是否有选区button.addEventListener(click, function (e) { const selection window.getSelection(); if (selection selection.toString()) { e.preventDefault(); return; } toggle(); });如果用户真的是在复制文本选区非空就忽略这次点击。第二层在移动端增加touchstart事件标记避免长按选择文本后松手误触。这个坑不只在 ponytail 里会发生任何“文本区 按钮”的布局都可能踩到建议大家写通用组件时直接内置判断。4.3 SSR / SSG 环境下的初始化时机在 Next.js、Nuxt 这类 SSR 框架中使用 ponytail还有一个隐蔽问题服务端已经渲染出完整文本客户端水合时组件会重新创建 DOM。如果你在useEffect或mounted中初始化 ponytail组件销毁又重建时可能出现重复实例页面上出现两个“展开”按钮这是最典型的表现。React 里的正确写法是绑定生命周期卸载时销毁实例import { useEffect, useRef } from react; import Ponytail from ponytail; export default function FoldableText({ text, lines 3 }) { const ref useRef(null); useEffect(() { const instance new Ponytail(ref.current, { maxLines: lines }); return () instance.destroy(); }, [lines, text]); return div ref{ref}{text}/div; }Vue 中也类似在onMounted里创建实例onBeforeUnmount里调用destroy()。还要注意一个细节如果ref.current的内容在useEffect执行前被框架重新渲染那么初始化脚本读取到的是最新 DOM比较安全否则需要把初始化放到requestAnimationFrame里。我自己的经验是框架相关的问题大多来自“实例没有随组件销毁”养成生命周期配对的习惯能省很多事。4.4 与 CSS 框架的 reset 冲突接入 Tailwind CSS 或 Normalize.css 后按钮的默认样式会被清掉。比如 Tailwind 的 preflight 会重置border、background导致插件按钮只剩下裸文本看起来非常突兀。我踩到后没有选择在 JS 里强行内联样式而是给按钮类名加了一个“最小可用样式”推荐块.ponytail-btn { border: 0; background: none; padding: 0 4px; margin: 0; font: inherit; line-height: inherit; color: inherit; cursor: pointer; }这组样式几乎兼容所有 reset 方案又不会和业务主题打架。如果你用的是组件库可能还要额外覆盖它们自带的按钮内边距。始终记得插件只负责行为不强行替业务做视觉决定。5. 进阶 skill让 ponytail 融入真实项目把插件跑通不难难的是在真实项目里优雅地使用。这一节我分享几个“用一段时间才能总结出来”的进阶技巧也正好对应平时大家搜的“ponytail skill”。5.1 封装 Vue / React 组件把 ponytail 封装成组件能避免业务代码到处new Ponytail。下面是一个极简的 Vue 组件模板script setup import { ref, onMounted, onBeforeUnmount } from vue; import Ponytail from ponytail; const props defineProps({ text: { type: String, required: true }, lines: { type: Number, default: 3 } }); const rootRef ref(null); let instance null; onMounted(() { rootRef.value.textContent props.text; instance new Ponytail(rootRef.value, { maxLines: props.lines }); }); onBeforeUnmount(() { if (instance) instance.destroy(); }); /script template div refrootRef/div /template关键在于把text和lines作为 props 传入组件内部在 mount 时创建实例卸载时销毁。如果后续要支持动态修改lines就在watch里调用instance.update({ maxLines: newVal })不要贸然销毁重建否则动画状态会丢失。React 版本同理用useRefuseEffect即可。封装成组件之后页面里就像使用普通文本组件一样简单FoldableText :textitem.summary :lines3 /5.2 动态内容更新后的重算方法很多列表页是异步加载数据的。第一屏的内容初始化后用户点击分页或者通过搜索切换数据源容器内文本变了但 ponytail 实例还停留在旧状态。这时候要用update()方法const instance new Ponytail(el); // 数据更新后 instance.update();如果你还改了maxLines配置也可以直接传新配置instance.update({ maxLines: 5 });update()会重新读取元素宽度、文字内容、字体状态再做一次折叠判断。动态宽度变化也需要重算比如用户点击“列表 / 卡片”切换布局容器宽度变了行高不变但每行能容纳的字数变了。建议配合 ResizeObserver 监听容器宽度变化并做一帧节流const ro new ResizeObserver(() { requestAnimationFrame(() instance.update()); }); ro.observe(el.parentElement);这里要提醒ResizeObserver回调在连续 resize 时触发频率很高直接用update()会有一连串重排。用requestAnimationFrame包一层能保证每帧最多执行一次性能友好得多。5.3 列表性能优化IntersectionObserver 懒初始化一个后台操作日志页面可能同时渲染上百条记录每条记录都有摘要文本。如果页面加载的一瞬间同时为 100 个元素创建实例即使插件很轻也会出现可以感知的卡顿尤其是低端设备。解决办法是利用 IntersectionObserver让文本进入视口附近才开始初始化const io new IntersectionObserver((entries) { entries.forEach((entry) { if (entry.isIntersecting) { new Ponytail(entry.target); io.unobserve(entry.target); } }); }, { rootMargin: 200px 0px }); document.querySelectorAll(.summary-text).forEach((el) io.observe(el));rootMargin: 200px 0px的意思是提前 200px 开始处理用户还没看到就已经初始化完成基本无感。这个技巧在首屏性能测试中效果很明显建议在长列表页面直接采用。初始化完成后再unobserve避免重复创建实例。特别注意如果元素在初始化时处于display: none比如 Tab 未激活IntersectionObserver 可能不会触发。正确做法是在 Tab 显示后再扫描一次或者在init()前确保所有目标元素已经可见。5.4 无障碍细节键盘操作与 aria-expanded很多前端做文本折叠时把“展开”做成了一个普通的span配上click事件就完事。这在无障碍层面几乎是不合格的键盘用户无法聚焦屏幕阅读器读不到含义也没有动态状态反馈。ponytail 默认生成的按钮是原生button自带可聚焦和键盘操作能力。同时插件会自动维护两个 ARIA 属性aria-expanded表示当前展开状态读屏器会播报“已展开 / 已折叠”aria-controls指向被它控制的内容区域 ID。如果你要自定义按钮元素记得自己补上tabindex0和键盘事件处理否则按下 Enter 或 Space 无法触发。更进阶的做法是在折叠状态下对隐藏的完整文本区域设置aria-hiddentrue让屏幕阅读器的朗读内容与视觉展示保持一致。这也是我在产品上线后被一个做企业官网的客户逼着补上的细节补完后测试通过率高了不少。最后再分享一个小技巧如果你也想自己实现类似功能或者想给 ponytail 加上一套更顺滑的过渡动画我的建议是不要试图精确计算展开后的最终高度来驱动动画直接给max-height一个足够大的上限值比如 2000px配合transition: max-height 0.2s ease-out视觉上很接近“由折到展”的平滑效果代码却省一大截。实际测试中这个方案对大多数文本都够用而且不容易出现展开高度计算完又被字体加载影响的问题。用 ponytail 处理了一段时间后我最大的感受是长文本截断看起来是一个小功能但它横跨布局、字体、事件、无障碍每个细节都可能成为新的 bug 来源。与其在十几个项目里重复造半成品不如把这些约束集中在一个小插件里处理。目前它已经用在我的博客摘要、内部系统列表和几个移动端页面上表现都很稳定。后面如果再遇到新坑我会继续补进这个使用笔记里。

相关新闻

Claude Code实战:从零搭建全栈AI应用全记录

Claude Code实战:从零搭建全栈AI应用全记录

如果你和我一样,是个习惯把需求丢给聊天窗口、再把代码手工贴回工程的全栈开发者,我强烈建议你试试 Claude Code。上个周末我把一个搁置了快一个月的全栈 AI 应用项目翻出来收尾,改用 Claude Code 在终端里从头跑了一遍:初始化目录…

2026/10/8 21:29:07 阅读更多 →
pi 极简编码代理:4 个工具与 oh-my-pi 全家桶实战

pi 极简编码代理:4 个工具与 oh-my-pi 全家桶实战

1. 当"全能"变成负担:我为什么开始重新审视编码代理的工具边界第一次接触 Claude Code 的时候,我承认自己被震撼到了。一个终端里的编码代理,能读文件、能改代码、能跑命令、能理解整个项目结构,几乎把"AI 结对编程…

2026/10/8 21:29:07 阅读更多 →
从Agent到多Agent协作:用AI完成论文写作全流程实战指南

从Agent到多Agent协作:用AI完成论文写作全流程实战指南

1. 为什么写论文这件事值得引入Agent 先交代一下背景。今年我把一篇综述论文的初稿,真正意义上交给了“一个Agent团队”去完成。不是用ChatGPT开个对话窗口、问它“帮我写一段引言”这种零散操作,而是搭建了一套能自主行动、分工协作的多Agent系统&#…

2026/10/8 21:28:04 阅读更多 →

最新新闻

Trae IDE 评测体验:用 MCP Server 打通 Figma AI Bridge,把设计稿一键转成前端代码

Trae IDE 评测体验:用 MCP Server 打通 Figma AI Bridge,把设计稿一键转成前端代码

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:57:25 阅读更多 →
【Bug已解决】openclaw log file too large / Disk space exhausted by logs — OpenClaw 日志文件过大解决方案与 TaoToken 统

【Bug已解决】openclaw log file too large / Disk space exhausted by logs — OpenClaw 日志文件过大解决方案与 TaoToken 统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:57:25 阅读更多 →
【保姆级教程】Windows 本地 AI 智能体 OpenClaw v2.7.9 部署实录:从安装包到 TaoToken 通道配置

【保姆级教程】Windows 本地 AI 智能体 OpenClaw v2.7.9 部署实录:从安装包到 TaoToken 通道配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:57:25 阅读更多 →
MonkeyCode vs Cursor vs Copilot:为什么我最终把 Base URL 改到 TaoToken

MonkeyCode vs Cursor vs Copilot:为什么我最终把 Base URL 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:57:25 阅读更多 →
Cursor 2.0 全局编辑重构:Spring Boot 3.4 多模态视图驱动的代码治理实战|TaoToken 统一 Key 接入

Cursor 2.0 全局编辑重构:Spring Boot 3.4 多模态视图驱动的代码治理实战|TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:57:25 阅读更多 →
智能体AI(Agentic AI)学习路径指南:用TaoToken统一Key跑通工具调用与多步推理

智能体AI(Agentic AI)学习路径指南:用TaoToken统一Key跑通工具调用与多步推理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:56:20 阅读更多 →

日新闻

抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:03 阅读更多 →
AI 编程 Trae 国内版与国际版一篇讲透:TaoToken 统一 Key 接入实测

AI 编程 Trae 国内版与国际版一篇讲透:TaoToken 统一 Key 接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:06 阅读更多 →
Claude Desktop 配置第三方推理接口教程:用 TaoToken 统一 Key 打通 API 调用

Claude Desktop 配置第三方推理接口教程:用 TaoToken 统一 Key 打通 API 调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:07 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →