Web API
提供了浏览器 Web API 的简化封装,包括剪贴板操作和权限查询。
Clipboard - 剪贴板
统一的剪贴板读写 API,支持文本和 Blob 数据。
复制文本
typescript
import { clipboard } from '@cat-kit/fe'
// 复制简单文本
await clipboard.copy('Hello, World!')
// 复制按钮示例
button.addEventListener('click', async () => {
try {
await clipboard.copy('复制的内容')
alert('复制成功')
} catch (error) {
alert('复制失败:' + error.message)
}
})复制 Blob 数据
typescript
import { clipboard } from '@cat-kit/fe'
// 复制图片
const response = await fetch('image.png')
const blob = await response.blob()
await clipboard.copy(blob)
// 复制 Canvas 内容
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')
canvas?.toBlob(async blob => {
if (blob) {
await clipboard.copy(blob)
console.log('Canvas 内容已复制到剪贴板')
}
})复制多个项目
typescript
import { clipboard } from '@cat-kit/fe'
// 同时复制文本和图片
const text = '图片描述'
const imageBlob = await fetch('image.png').then(r => r.blob())
await clipboard.copy([text, imageBlob])读取剪贴板
typescript
import { clipboard } from '@cat-kit/fe'
// 读取文本
const text = await clipboard.readText()
console.log('剪贴板内容:', text)
// 读取所有数据(返回 Blob 数组)
const blobs = await clipboard.read()
for (const blob of blobs) {
console.log('类型:', blob.type)
if (blob.type.startsWith('image/')) {
// 处理图片
const url = URL.createObjectURL(blob)
console.log('图片 URL:', url)
} else if (blob.type === 'text/plain') {
// 处理文本
const text = await blob.text()
console.log('文本:', text)
}
}粘贴事件处理
typescript
import { clipboard } from '@cat-kit/fe'
// 监听粘贴事件
document.addEventListener('paste', async e => {
e.preventDefault()
try {
const blobs = await clipboard.read()
for (const blob of blobs) {
if (blob.type.startsWith('image/')) {
// 处理粘贴的图片
const img = document.createElement('img')
img.src = URL.createObjectURL(blob)
document.body.appendChild(img)
} else if (blob.type === 'text/plain') {
// 处理粘贴的文本
const text = await blob.text()
console.log('粘贴的文本:', text)
}
}
} catch (error) {
console.error('读取剪贴板失败:', error)
}
})图片编辑器复制功能
typescript
import { clipboard } from '@cat-kit/fe'
class ImageEditor {
private canvas: HTMLCanvasElement
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas
}
async copyToClipboard() {
return new Promise<void>((resolve, reject) => {
this.canvas.toBlob(async blob => {
if (!blob) {
reject(new Error('无法生成图片'))
return
}
try {
await clipboard.copy(blob)
resolve()
} catch (error) {
reject(error)
}
}, 'image/png')
})
}
async pasteFromClipboard(): Promise<HTMLImageElement> {
const blobs = await clipboard.read()
const imageBlob = blobs.find(b => b.type.startsWith('image/'))
if (!imageBlob) {
throw new Error('剪贴板中没有图片')
}
const img = new Image()
img.src = URL.createObjectURL(imageBlob)
await new Promise(resolve => (img.onload = resolve))
return img
}
}权限处理
typescript
import { clipboard, queryPermission } from '@cat-kit/fe'
async function copyWithPermissionCheck(text: string) {
// 检查写入权限
const hasWritePermission = await queryPermission('clipboard-write')
if (!hasWritePermission) {
alert('需要剪贴板写入权限')
return
}
try {
await clipboard.copy(text)
console.log('复制成功')
} catch (error) {
console.error('复制失败:', error)
}
}
async function readWithPermissionCheck() {
// 检查读取权限
const hasReadPermission = await queryPermission('clipboard-read')
if (!hasReadPermission) {
alert('需要剪贴板读取权限')
return
}
try {
const text = await clipboard.readText()
console.log('读取成功:', text)
} catch (error) {
console.error('读取失败:', error)
}
}Permission - 权限查询
查询浏览器 Web API 权限状态。
基本用法
typescript
import { queryPermission } from '@cat-kit/fe'
// 查询剪贴板读取权限
const canReadClipboard = await queryPermission('clipboard-read')
console.log('可以读取剪贴板:', canReadClipboard)
// 查询剪贴板写入权限
const canWriteClipboard = await queryPermission('clipboard-write')
console.log('可以写入剪贴板:', canWriteClipboard)
// 查询通知权限
const canNotify = await queryPermission('notifications')
console.log('可以发送通知:', canNotify)
// 查询地理位置权限
const canUseGeo = await queryPermission('geolocation')
console.log('可以使用地理位置:', canUseGeo)支持的权限类型
typescript
type WebPermissionName =
| 'geolocation'
| 'notifications'
| 'persistent-storage'
| 'push'
| 'screen-wake-lock'
| 'xr-spatial-tracking'
| 'clipboard-read' // 剪贴板读取(扩展)
| 'clipboard-write' // 剪贴板写入(扩展)权限状态
权限查询返回布尔值:
true: 权限已授予(granted)false: 权限被拒绝(denied)或需要提示(prompt)
实用示例
条件渲染 UI
typescript
import { queryPermission } from '@cat-kit/fe'
async function setupUI() {
const canUseNotifications = await queryPermission('notifications')
const notificationButton = document.querySelector('#notifyButton')
if (notificationButton) {
notificationButton.disabled = !canUseNotifications
notificationButton.title = canUseNotifications
? '发送通知'
: '通知权限未授予'
}
}功能降级
typescript
import { queryPermission, clipboard } from '@cat-kit/fe'
async function copyText(text: string) {
const hasClipboardAPI = await queryPermission('clipboard-write')
if (hasClipboardAPI) {
// 使用 Clipboard API
await clipboard.copy(text)
} else {
// 降级到旧方法
const textarea = document.createElement('textarea')
textarea.value = text
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
}
}权限请求流程
typescript
import { queryPermission } from '@cat-kit/fe'
async function requestNotificationPermission() {
// 先查询当前状态
const hasPermission = await queryPermission('notifications')
if (hasPermission) {
console.log('已有通知权限')
return true
}
// 请求权限
const result = await Notification.requestPermission()
if (result === 'granted') {
console.log('用户授予了通知权限')
return true
} else {
console.log('用户拒绝了通知权限')
return false
}
}API 参考
clipboard.copy
typescript
function copy(data: string | Blob | Array<string | Blob>): Promise<void>参数:
data: 要复制的数据,可以是文本、Blob 或它们的数组
返回:
Promise<void>: 复制完成
异常:
- 用户拒绝权限
- 浏览器不支持 Clipboard API
- 数据类型不正确
clipboard.read
typescript
function read(): Promise<Blob[]>返回:
Promise<Blob[]>: 剪贴板中的所有项目(Blob 数组)
异常:
- 用户拒绝权限
- 浏览器不支持 Clipboard API
clipboard.readText
typescript
function readText(): Promise<string>返回:
Promise<string>: 剪贴板中的文本内容
异常:
- 用户拒绝权限
- 浏览器不支持 Clipboard API
queryPermission
typescript
function queryPermission(name: WebPermissionName): Promise<boolean>参数:
name: 权限名称
返回:
Promise<boolean>: 是否有权限(true表示已授予,false表示未授予或被拒绝)
浏览器兼容性
Clipboard API
- Chrome: 66+(文本),76+(图片)
- Firefox: 63+(文本),90+(图片)
- Safari: 13.1+
- Edge: 79+
Permissions API
- Chrome: 43+
- Firefox: 46+
- Safari: 16+(部分支持)
- Edge: 79+
注意事项
- HTTPS 要求:Clipboard API 需要在 HTTPS 环境或 localhost 下使用
- 用户手势:某些浏览器要求在用户手势(如点击)触发的事件中调用
- 权限提示:首次使用会提示用户授权
- 跨域限制:只能在同源页面中使用
- 焦点要求:某些浏览器要求页面必须获得焦点才能读写剪贴板
