نحوه چسباندن تصاویر

روش مدرن

استفاده از API کلیپ‌بورد ناهمگام

برای خواندن تصاویر از کلیپ‌بورد کاربر به صورت برنامه‌نویسی شده، یعنی پس از کلیک روی دکمه، می‌توانید از متد read() از API کلیپ‌بورد Async استفاده کنید. اگر هنوز اجازه خواندن از کلیپ‌بورد داده نشده باشد، فراخوانی navigator.clipboard.read() در اولین فراخوانی متد، آن را درخواست می‌کند.

const pasteButton = document.querySelector('#paste-button');

pasteButton.addEventListener('click', async () => {
  try {
    const clipboardItems = await navigator.clipboard.read();
    for (const clipboardItem of clipboardItems) {
      const imageTypes = clipboardItem.types.find(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        const blob = await clipboardItem.getType(imageType);
        // Do something with the image blob.
      }
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});

Browser Support

  • کروم: ۷۶.
  • لبه: ۷۹.
  • فایرفاکس: ۱۲۷.
  • سافاری: ۱۳.۱.

Source

روش کلاسیک

به رویداد paste گوش دهید

روش کلاسیک برای چسباندن تصاویر، استفاده از API کلیپ‌بورد (همزمان) است که به شما امکان دسترسی به فیلد clipboardData را در داخل رویداد Document: paste می‌دهد. با این حال، این روش محدودیت‌هایی دارد، به عنوان مثال، به دلیل همزمان بودن، چسباندن حجم زیادی از داده‌ها می‌تواند صفحه را مسدود کند.

document.addEventListener('paste', async (e) => {
  e.preventDefault();

  for (const clipboardItem of e.clipboardData.files) {
    if (clipboardItem.type.startsWith('image/')) {
      // Do something with the image file.
    }
  }
});

Browser Support

  • کروم: ۶۶.
  • لبه: ۷۹.
  • فایرفاکس: ۶۳.
  • سافاری: ۱۳.۱.

Source

بهبود تدریجی

برای مرورگرهایی که از Async Clipboard API پشتیبانی نمی‌کنند، دسترسی به کلیپ‌بورد کاربر از طریق برنامه‌نویسی (مثلاً با کلیک روی یک دکمه) غیرممکن است. بنابراین برای دسترسی به کلیپ‌بورد کاربر در یک رویداد paste ، می‌توانید از Async Clipboard API استفاده کنید و به Clipboard API (همزمان) برگردید.

اشیاء ClipboardItem که از navigator.clipboard.read می‌آیند، یک فیلد types دارند که یک آرایه است، و اشیاء File که از event.clipboardData.files می‌آیند، یک فیلد type دارند که یک رشته است. می‌توانید به صورت شرطی هر یک از فیلدهای type یا types را برای تصاویر موجود در کلیپ‌بورد بررسی کنید:

document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const clipboardItems = typeof navigator?.clipboard?.read === 'function' ? await navigator.clipboard.read() : e.clipboardData.files;

  for (const clipboardItem of clipboardItems) {
    let blob;
    if (clipboardItem.type?.startsWith('image/')) {
      // For files from `e.clipboardData.files`.
      blob = clipboardItem
      // Do something with the blob.
    } else {
      // For files from `navigator.clipboard.read()`.
      const imageTypes = clipboardItem.types?.filter(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        blob = await clipboardItem.getType(imageType);
        // Do something with the blob.
      }
    }
  }
});

مطالعه بیشتر

  • رابط برنامه‌نویسی کلیپ‌بورد در MDN
  • رفع انسداد دسترسی به کلیپ‌بورد در web.dev

نسخه آزمایشی

اچ‌تی‌ام‌ال

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
    />
    <title>How to paste images</title>
  </head>
  <body>
    <h1>How to paste images</h1>
    <p>Hit <kbd>⌘</kbd> + <kbd>v</kbd> (for macOS) or <kbd>ctrl</kbd> + <kbd>v</kbd>
      (for other operating systems) to paste images anywhere in this page.
    </p>
  </body>
</html>

سی‌اس‌اس


        :root {
  color-scheme: dark light;
}

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

button {
  display: block;
}
        

جی‌اس


        document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const clipboardItems = typeof navigator?.clipboard?.read === 'function' ? await navigator.clipboard.read() : e.clipboardData.files;

  for (const clipboardItem of clipboardItems) {
    let blob;
    if (clipboardItem.type?.startsWith('image/')) {
      // For files from `e.clipboardData.files`.
      blob = clipboardItem
      // Do something with the blob.
      appendImage(blob);
    } else {
      // For files from `navigator.clipboard.read()`.
      const imageTypes = clipboardItem.types?.filter(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        blob = await clipboardItem.getType(imageType);
        // Do something with the blob.
        appendImage(blob);
      }
    }
  }
});

const appendImage = (blob) => {
  const img = document.createElement('img');
  img.src = URL.createObjectURL(blob);
  document.body.append(img);
};