Skip to content

预览系统

AI-SideChat 提供了现代化的毛玻璃预览功能,让你无需跳转即可查看收藏的完整内容。

悬浮预览

触发方式

鼠标悬停在悬浮坞中的任意收藏条目上,会自动弹出预览窗口。

预览内容

预览窗口显示:

  • 问题:完整的用户提问
  • 回答:AI 的完整回答(HTML 格式)
  • 格式:保留原始格式(代码块、列表、粗体等)
  • 代码复制:代码块带复制按钮

视觉设计

  • 毛玻璃效果backdrop-filter: blur(10px)
  • 半透明背景background: rgba(255, 255, 255, 0.9)
  • 阴影box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1)
  • 圆角border-radius: 12px

钉住功能

如何钉住

  1. 悬停显示预览窗口
  2. 点击右上角的 📌 图标
  3. 预览窗口会固定在屏幕上

钉住后的特性

  • 持久显示:不会因为鼠标移开而消失
  • 可拖拽:点击标题栏拖拽移动
  • 独立窗口:可以边看预览边操作其他内容
  • 关闭按钮:点击 ❌ 关闭

拖拽移动

实现方式

javascript
let isDragging = false
let offsetX, offsetY

titleBar.addEventListener('mousedown', (e) => {
  isDragging = true
  offsetX = e.clientX - preview.offsetLeft
  offsetY = e.clientY - preview.offsetTop
})

document.addEventListener('mousemove', (e) => {
  if (isDragging) {
    preview.style.left = (e.clientX - offsetX) + 'px'
    preview.style.top = (e.clientY - offsetY) + 'px'
  }
})

document.addEventListener('mouseup', () => {
  isDragging = false
})

拖拽体验

  • 平滑移动:实时跟随鼠标
  • 边界限制:不会拖出屏幕
  • 视觉反馈:拖拽时光标变化

代码复制

自动检测

预览窗口会自动识别代码块:

javascript
const codeBlocks = preview.querySelectorAll('pre code')
codeBlocks.forEach(block => {
  addCopyButton(block)
})

复制按钮

每个代码块右上角会显示复制按钮:

  • 默认:📋 图标
  • 悬停:高亮显示
  • 点击后:显示 ✅,提示"已复制"
  • 2 秒后:恢复原状

实现代码

javascript
function addCopyButton(codeBlock) {
  const button = document.createElement('button')
  button.textContent = '复制'
  button.onclick = () => {
    navigator.clipboard.writeText(codeBlock.textContent)
    button.textContent = '已复制 ✅'
    setTimeout(() => {
      button.textContent = '复制'
    }, 2000)
  }
  codeBlock.parentElement.appendChild(button)
}

关键词高亮

搜索时高亮

当在搜索框中输入关键词时:

  1. 预览窗口中的匹配文本会高亮
  2. 使用黄色背景标记
  3. 便于快速找到相关内容

高亮实现

javascript
function highlightKeyword(text, keyword) {
  const regex = new RegExp(keyword, 'gi')
  return text.replace(regex, match => {
    return `<mark>${match}</mark>`
  })
}

样式

css
mark {
  background-color: #fff59d;
  color: #000;
  padding: 2px 4px;
  border-radius: 2px;
}

响应式设计

位置计算

预览窗口会智能选择显示位置:

  • 默认:鼠标右侧
  • 右侧空间不足:显示在左侧
  • 底部空间不足:向上偏移
javascript
function calculatePosition(mouseX, mouseY) {
  const previewWidth = 400
  const previewHeight = 600

  let left = mouseX + 20
  let top = mouseY - 100

  if (left + previewWidth > window.innerWidth) {
    left = mouseX - previewWidth - 20
  }

  if (top + previewHeight > window.innerHeight) {
    top = window.innerHeight - previewHeight - 20
  }

  return { left, top }
}

移动端适配

规划中

移动端版本将采用全屏预览模式,提供更好的阅读体验。

性能优化

懒加载

  • 只在悬停时才渲染预览内容
  • 避免一次性渲染所有收藏的预览

虚拟 DOM

  • 使用 innerHTML 而非逐个创建元素
  • 提高大内容的渲染速度

防抖处理

javascript
let hoverTimeout
element.addEventListener('mouseenter', () => {
  hoverTimeout = setTimeout(() => {
    showPreview()
  }, 300)
})

element.addEventListener('mouseleave', () => {
  clearTimeout(hoverTimeout)
})

使用技巧

💡 技巧 1:快速浏览

悬停在多个收藏上快速浏览内容,找到需要的那一条。

💡 技巧 2:对比查看

钉住多个预览窗口,对比不同 AI 的回答。

💡 技巧 3:边看边操作

钉住预览窗口,边看内容边在编辑器中编写代码。

💡 技巧 4:复制代码

直接从预览窗口复制代码,无需跳转到原页面。

下一步

Released under the MIT License.