diff --git a/content/post/2026-01-24-Artalk评论系统实现段落评论功能/0ed440d66514652540edc35c76a676b7.jpg b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/0ed440d66514652540edc35c76a676b7.jpg new file mode 100644 index 00000000..9476aa21 Binary files /dev/null and b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/0ed440d66514652540edc35c76a676b7.jpg differ diff --git a/content/post/2026-01-24-Artalk评论系统实现段落评论功能/3.png b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/3.png new file mode 100644 index 00000000..57071607 Binary files /dev/null and b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/3.png differ diff --git a/content/post/2026-01-24-Artalk评论系统实现段落评论功能/index.md b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/index.md new file mode 100644 index 00000000..712653ab --- /dev/null +++ b/content/post/2026-01-24-Artalk评论系统实现段落评论功能/index.md @@ -0,0 +1,254 @@ +--- +title: "Artalk评论系统实现段落评论功能" +date: 2026-01-24T19:40:00+08:00 +draft: false +tags: ["Artalk", "博客优化", "JS", "CSS"] +categories: ["折腾记录"] +--- + +最近在番茄小说上看书,发现它的**段落评论**功能是真的好用。看到有共鸣的句子,选中就能直接看别人的评论或者自己吐槽两句。 + +![Artalk评论系统实现段落评论功能](0ed440d66514652540edc35c76a676b7.jpg) + +我就在想,我的博客是不是也能整一个?毕竟现在还在坚持写博客的,谁还没点表达欲呢? + +下午没事折腾了一下,试着给我的 Artalk 评论系统加上了这个功能。效果还凑合,选中文字后会弹出一个“引用评论”的按钮,点击就能自动跳转到评论区并引用选中的内容。 + +![Artalk评论系统实现段落评论功能](3.png) + +稍微整理了一下代码,分享给有需要的朋友。我是个前端小白,代码写得比较粗糙,大佬们见笑了。无论你用什么主题,只要是 Artalk 评论系统,理论上都能适配。 + +## 实现思路 + +逻辑其实挺简单的,主要是以下几步: + +1. **监听选择**:监听用户的鼠标选取操作 (`mouseup`)。 +2. **计算位置**:获取选中范围的坐标,把按钮定位到鼠标或者选区上方。 +3. **点击交互**:点击按钮后,获取选中的文字,平滑滚动到评论区,把文字填进输入框。 +4. **细节优化**:做了一些防抖处理,简单适配了一下移动端和暗黑模式(这个必须有!)。 + +## 代码实现 + +### 1. HTML 结构 + +不需要手动写 HTML,直接用 JS 动态生成插入到 body 里就行,这样省事点。 + +### 2. CSS 样式 + +这块我调了半天。一开始用了毛玻璃效果 (`backdrop-filter`),结果发现页面滚动的时候有点掉帧,为了性能我把它去掉了,改成了更实用的深色/浅色背景,顺便加了 `will-change` 属性开启硬件加速。 + +把下面这段代码加到你的自定义 CSS 里: + +```css +/* 选中弹出按钮样式 */ +#selection-popup { + position: fixed; + display: none; + background: rgba(30, 30, 30, 0.9); + color: #fff; + padding: 8px 16px; + border-radius: 8px; + font-size: 14px; + cursor: pointer; + z-index: 2147483647; /* 堆叠层级拉满 */ + transform: translate(-50%, -100%); + pointer-events: auto; + box-shadow: 0 4px 12px rgba(0,0,0,0.15); + transition: opacity 0.2s, transform 0.2s; + font-weight: 500; + line-height: 1.4; + user-select: none; + -webkit-user-select: none; + align-items: center; + gap: 6px; + white-space: nowrap; + will-change: transform, opacity; /* 性能优化关键 */ + animation: popIn 0.2s cubic-bezier(0.18, 0.89, 0.32, 1.28); +} + +/* 弹出动画 */ +@keyframes popIn { + 0% { transform: translate(-50%, -80%) scale(0.9); opacity: 0; } + 100% { transform: translate(-50%, -100%) scale(1); opacity: 1; } +} + +/* 小三角箭头 */ +#selection-popup::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + margin-left: -6px; + border-width: 6px; + border-style: solid; + border-color: rgba(30, 30, 30, 0.9) transparent transparent transparent; +} + +/* 悬停效果 */ +#selection-popup:hover { + transform: translate(-50%, -110%) scale(1.05); + background: #000; + box-shadow: 0 6px 16px rgba(0,0,0,0.25); +} + +/* 暗黑模式适配 */ +[data-theme="dark"] #selection-popup { + background: rgba(255, 255, 255, 0.95); + color: #000; + box-shadow: 0 4px 12px rgba(0,0,0,0.3); +} + +[data-theme="dark"] #selection-popup::after { + border-color: rgba(255, 255, 255, 0.95) transparent transparent transparent; +} + +[data-theme="dark"] #selection-popup:hover { + background: #fff; +} +``` + +### 3. JavaScript 逻辑 + +把这段 JS 加到你的 `main.js` 或者 footer 的 `