✨️ 复制成功,转载请标注本文地址

全局复制事件监听与提示浮层

411 字
2 分钟
全局复制事件监听与提示浮层

一、功能说明#

  • 监听全局 copy 事件
  • 顶部滑入提示浮层,3 秒后自动消失
  • 进度条从左到右动画,模拟倒计时
  • 支持浅色/深色模式

二、实现细节#

Svelte 组件

src/components/common/CopyMessage.svelte
<script lang="ts">
import { onMount } from "svelte";
const SHOW_DURATION = 3000;
let isVisible = $state(false);
let hideTimeout: ReturnType<typeof setTimeout> | null = null;
const showCopyMessage = () => {
if (hideTimeout) {
clearTimeout(hideTimeout);
hideTimeout = null;
}
isVisible = false;
setTimeout(() => {
isVisible = true;
hideTimeout = setTimeout(() => {
isVisible = false;
}, SHOW_DURATION);
}, 10); // 短暂延迟触发重排
};
const handleCopy = () => {
const selection = window.getSelection();
if (selection?.toString().trim()) showCopyMessage();
};
onMount(() => {
document.addEventListener("copy", handleCopy);
return () => {
document.removeEventListener("copy", handleCopy);
if (hideTimeout) clearTimeout(hideTimeout);
};
});
</script>
<div class="copy-message" class:show={isVisible}>
<div class="message-background">
<div class="progress-bar" class:active={isVisible}></div>
</div>
<div class="message-content">
<span class="text">✨️ 复制成功,转载请标注本文地址</span>
</div>
</div>
<style>
.copy-message {
--duration: 3000ms;
--height: 50px;
--transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
--bg-gradient: linear-gradient(90deg, var(--primary) 0%, var(--primary) 25%, var(--primary) 50%, var(--primary) 75%, var(--primary) 100%);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: var(--height);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
transform: translateY(-100%);
transition: var(--transition), opacity 0.4s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
overflow: hidden;
opacity: 0;
}
.copy-message.show { transform: translateY(0); opacity: 1; }
.copy-message .message-background {
position: absolute;
inset: 0;
background: var(--bg-gradient);
z-index: 1;
}
.copy-message .progress-bar {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0) 100%
);
z-index: 2;
transform: translateX(0);
transition: transform 0ms;
}
.copy-message .progress-bar.active {
transform: translateX(200%);
transition: transform var(--duration) linear;
}
.copy-message .message-content {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 600;
color: white;
position: relative;
z-index: 3;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
@media (max-width: 768px) {
.copy-message { --height: 44px; }
.copy-message .message-content {
font-size: 14px;
padding: 0 16px;
text-align: center;
}
}
@media (prefers-color-scheme: dark) {
.copy-message {
--bg-gradient: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
}
}
</style>

三、使用方式#

Layout.astro 中全局挂载(位于 <MusicManager /> 之后、<slot /> 之前):

src/layouts/Layout.astro
<ConfigCarrier />
<MusicManager />
<CopyMessage client:load />
<slot />

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

全局复制事件监听与提示浮层
https://godze.online/posts/firefly魔改/全局复制事件监听与提示浮层/
作者
Vafail
发布于
2026-05-01
许可协议
CC BY-NC-SA 4.0

评论区

公告
欢迎来到我的博客!
分类
标签
最新动态
站点统计
文章
61
分类
6
标签
8
总字数
136,467
运行时长
0
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.15.3
文章许可
CC BY-NC-SA 4.0