欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS實(shí)現(xiàn)復(fù)制粘貼文字及圖片功能

 更新時(shí)間:2024年07月17日 08:57:21   作者:Code技術(shù)分享  
Clipboard?API?是一組用于在瀏覽器中操作剪貼板的?JavaScript?API,它允許開(kāi)發(fā)者在網(wǎng)頁(yè)上讀取和寫(xiě)入剪貼板內(nèi)容,實(shí)現(xiàn)復(fù)制、剪切和粘貼等功能,這篇文章主要介紹了JS實(shí)現(xiàn)復(fù)制粘貼文字及圖片功能,需要的朋友可以參考下

一. 基于 Clipboard API 復(fù)制文字(推薦)

基本概念

Clipboard API 是一組用于在瀏覽器中操作剪貼板的 JavaScript API,它允許開(kāi)發(fā)者在網(wǎng)頁(yè)上讀取和寫(xiě)入剪貼板內(nèi)容,實(shí)現(xiàn)復(fù)制、剪切和粘貼等功能。Clipboard API 提供了一種在網(wǎng)頁(yè)上讀取和寫(xiě)入剪貼板內(nèi)容的方式,包括文本、圖像和其他類(lèi)型的數(shù)據(jù)。Clipboard API 適用于需要與用戶剪貼板進(jìn)行交互的網(wǎng)頁(yè)應(yīng)用,如實(shí)現(xiàn)一鍵復(fù)制、粘貼功能,或者在用戶復(fù)制特定內(nèi)容時(shí)自動(dòng)添加額外信息等。

https://developer.mozilla.org/zh-CN/docs/Web/API/Clipboard_API

主要方法

Clipboard API 提供了幾個(gè)關(guān)鍵的方法來(lái)實(shí)現(xiàn)剪貼板的讀寫(xiě)操作:

  • navigator.clipboard.writeText(text):將給定的文本復(fù)制到剪貼板。這是一個(gè)異步方法,會(huì)返回一個(gè) Promise 對(duì)象,成功時(shí) Promise 會(huì)被解析,失敗時(shí)會(huì)被拒絕。
  • navigator.clipboard.readText():從剪貼板讀取文本內(nèi)容。這也是一個(gè)異步方法,返回一個(gè) Promise 對(duì)象,解析后提供剪貼板中的文本內(nèi)容。
  • navigator.clipboard.write(data):寫(xiě)入更復(fù)雜的數(shù)據(jù)類(lèi)型到剪貼板,如文件、圖像等。data 參數(shù)是一個(gè)包含 ClipboardItem 對(duì)象的數(shù)組,每個(gè) ClipboardItem 對(duì)象代表剪貼板中的一項(xiàng)數(shù)據(jù)。這也是一個(gè)異步方法,返回一個(gè) Promise 對(duì)象。
  • navigator.clipboard.read():從剪貼板讀取更復(fù)雜的數(shù)據(jù)類(lèi)型,如文件、圖像等。這個(gè)方法會(huì)返回一個(gè) Promise 對(duì)象,解析后提供一個(gè)包含 ClipboardItem 對(duì)象的數(shù)組。

使用限制

  • 用戶授權(quán):由于安全和隱私的考慮,瀏覽器在使用 Clipboard API 時(shí)通常需要用戶授權(quán)。例如,在嘗試從剪貼板讀取或?qū)懭霐?shù)據(jù)時(shí),瀏覽器可能會(huì)要求用戶明確允許。
  • 安全上下文:Clipboard API 只能在安全的環(huán)境中操作剪貼板,如 HTTPS 頁(yè)面、localhost本機(jī)下。
  • 瀏覽器兼容性:雖然大多數(shù)現(xiàn)代瀏覽器都支持 Clipboard API,但仍有部分舊版瀏覽器可能不支持。因此,在使用時(shí)需要考慮瀏覽器的兼容性。

實(shí)際應(yīng)用示例

<template>
    <el-button type="primary" @click="handleCopy">復(fù)制文本</el-button>
    <div>{{ message }}</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const message = ref('復(fù)制的內(nèi)容')
const handleCopy = () => {
    navigator.clipboard
        .writeText(message.value)
        .then(() => {
            ElMessage({
                message: '復(fù)制成功',
                type: 'success',
            })
        })
        .catch((err) => {
            console.error('復(fù)制失敗:', err)
            ElMessage({
                message: '復(fù)制失敗',
                type: 'error',
            })
        })
}
</script>

二、基于 document.execCommand('copy')

document.execCommand('copy') 是一個(gè)在網(wǎng)頁(yè)上執(zhí)行復(fù)制操作的舊式API,屬于 Web API 的一部分,用于在不需要用戶交互(如點(diǎn)擊或按鍵)的情況下,通過(guò)腳本復(fù)制文本到剪貼板。然而,這個(gè)API在現(xiàn)代Web開(kāi)發(fā)中已經(jīng)被視為過(guò)時(shí)(deprecated),并在許多現(xiàn)代瀏覽器中受到限制或不再支持,尤其是在沒(méi)有用戶明確交互的情況下。

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand

缺陷

  • 只能操作input, textarea或具有contenteditable屬性的元素
  • execCommand 是同步操作,如果復(fù)制/粘貼大量數(shù)據(jù),可能會(huì)導(dǎo)致頁(yè)面出現(xiàn)卡頓現(xiàn)象,影響用戶體驗(yàn)。
  • 它只能將選中的內(nèi)容復(fù)制到剪貼板,無(wú)法向剪貼板任意寫(xiě)入內(nèi)容
  • 有些瀏覽器還會(huì)跳出提示框,要求用戶許可,這時(shí)在用戶做出選擇前,頁(yè)面會(huì)失去響應(yīng)。

實(shí)際應(yīng)用示例

<template>
    <el-button type="primary" @click="handleCopy2">復(fù)制文本2</el-button>
    <div>{{ message }}</div>
</template>
<script setup>
import {
    copyText,
    copyImage,
    imageUrlToBase64,
    parseBase64,
} from './common/copy'
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const message = ref('復(fù)制的內(nèi)容')
const handleCopy2 = () => {
    // 動(dòng)態(tài)創(chuàng)建 textarea 標(biāo)簽
    const textarea = document.createElement('textarea')
    // 將該 textarea 設(shè)為 readonly 防止 iOS 下自動(dòng)喚起鍵盤(pán),同時(shí)將 textarea 移出可視區(qū)域
    textarea.readOnly = 'readonly'
    textarea.style.position = 'absolute'
    textarea.style.left = '-9999px'
    textarea.style.opacity = '0'
    // 將要 copy 的值賦給 textarea 標(biāo)簽的 value 屬性
    textarea.value = message.value
    // 將 textarea 插入到 body 中
    document.body.appendChild(textarea)
    // 選中值并復(fù)制
    textarea.select()
    const result = document.execCommand('Copy')
    if (result) {
        ElMessage({
            message: '復(fù)制成功',
            type: 'success',
        })
    }
    document.body.removeChild(textarea)
}
</script>

說(shuō)明

clipboard.js 底層也是基于 document.execCommand去實(shí)現(xiàn)的

function createFakeElement(value) {
  var isRTL = document.documentElement.getAttribute('dir') === 'rtl';
  var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS
  fakeElement.style.fontSize = '12pt'; // Reset box model
  fakeElement.style.border = '0';
  fakeElement.style.padding = '0';
  fakeElement.style.margin = '0'; // Move element out of screen horizontally
  fakeElement.style.position = 'absolute';
  fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically
  var yPosition = window.pageYOffset || document.documentElement.scrollTop;
  fakeElement.style.top = "".concat(yPosition, "px");
  fakeElement.setAttribute('readonly', '');
  fakeElement.value = value;
  return fakeElement;
}
var fakeCopyAction = function fakeCopyAction(value, options) {
  var fakeElement = createFakeElement(value);
  options.container.appendChild(fakeElement);
  var selectedText = select_default()(fakeElement);
  command('copy');
  fakeElement.remove();
  return selectedText;
};

三、復(fù)制圖片功能

<template>
    <el-button type="primary" @click="handleCopyImage">復(fù)制圖片</el-button>
    <div>{{ message }}</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const message = ref('復(fù)制的內(nèi)容')
const handleCopyImage = async () => {
    //具體看下面的封裝
    await copyImage('https://cn.vitejs.dev/logo-with-shadow.png')
    ElMessage({
        message: '復(fù)制成功',
        type: 'success',
    })
}
</script>

四、封裝

/**
 * 圖片轉(zhuǎn)base64
 * @param {string} 圖片地址
 * @returns
 */
export const imageUrlToBase64 = (imageUrl) => {
    return new Promise((resolve, reject) => {
        let image = new Image()
        image.setAttribute('crossOrigin', 'Anonymous')
        image.src = imageUrl
        image.onload = function () {
            const canvas = document.createElement('canvas')
            canvas.width = image.width
            canvas.height = image.height
            const context = canvas.getContext('2d')
            context.drawImage(image, 0, 0, image.width, image.height)
            const base64Str = canvas.toDataURL('image/png')
            resolve(base64Str)
        }
        image.onerror = function (e) {
            reject(e)
        }
    })
}
/**
 * 轉(zhuǎn)換base64
 * @param {string} base64
 * @returns
 */
export function parseBase64(base64) {
    let re = new RegExp('data:(?<type>.*?);base64,(?<data>.*)')
    let res = re.exec(base64)
    if (res) {
        return {
            type: res.groups.type,
            ext: res.groups.type.split('/').slice(-1)[0],
            data: res.groups.data,
        }
    }
}
/**
 * 復(fù)制文字
 * @param {string} text  要復(fù)制的文本
 * @returns {boolean} true/false
 */
export const copyText = async (text) => {
    if (navigator && navigator.clipboard) {
        await navigator.clipboard.writeText(text)
        return true
    }
    // 動(dòng)態(tài)創(chuàng)建 textarea 標(biāo)簽
    const textarea = document.createElement('textarea')
    // 將該 textarea 設(shè)為 readonly 防止 iOS 下自動(dòng)喚起鍵盤(pán),同時(shí)將 textarea 移出可視區(qū)域
    textarea.readOnly = 'readonly'
    textarea.style.position = 'absolute'
    textarea.style.left = '-9999px'
    textarea.style.opacity = '0'
    // 將要 copy 的值賦給 textarea 標(biāo)簽的 value 屬性
    textarea.value = text
    // 將 textarea 插入到 body 中
    document.body.appendChild(textarea)
    // 選中值并復(fù)制
    textarea.select()
    const result = document.execCommand('Copy')
    document.body.removeChild(textarea)
    return result
}
/**
 * 復(fù)制圖片
 * @param {string} imageUrl 圖片地址
 * @param {boolean} isBase64 是否是base64
 */
export const copyImage = async (imageUrl, isBase64 = false) => {
    let base64Url = ''
    if (!isBase64) {
        base64Url = await imageUrlToBase64(imageUrl)
    } else base64Url = imageUrl
    const parsedBase64 = parseBase64(base64Url)
    let type = parsedBase64.type
    //將base64轉(zhuǎn)為Blob類(lèi)型
    let bytes = atob(parsedBase64.data)
    let ab = new ArrayBuffer(bytes.length)
    let ua = new Uint8Array(ab)
    for (let i = 0; i < bytes.length; i++) {
        ua[i] = bytes.charCodeAt(i)
    }
    let blob = new Blob([ab], { type })
    navigator.clipboard.write([new ClipboardItem({ [type]: blob })])
}

到此這篇關(guān)于JS實(shí)現(xiàn)復(fù)制粘貼文字以及圖片的文章就介紹到這了,更多相關(guān)js復(fù)制粘貼文字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論