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

هری تئودولو
هری تئودولو

روش مدرن

با استفاده از Async Clipboard API

برای خواندن تصاویر از کلیپ بورد کاربر به صورت برنامه نویسی، یعنی پس از کلیک روی دکمه، می توانید از متد read() API Async Clipboard استفاده کنید. اگر مجوز خواندن از کلیپ بورد هنوز اعطا نشده باشد، فراخوانی 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);
  }
});

پشتیبانی مرورگر

  • 86
  • 79
  • 13.1

منبع

روش کلاسیک

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

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

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.
    }
  }
});

پشتیبانی مرورگر

  • 66
  • 79
  • 63
  • 13.1

منبع

افزایش پیشرونده

برای مرورگرهایی که از Async Clipboard API پشتیبانی نمی کنند، دسترسی به کلیپ بورد کاربر به صورت برنامه نویسی غیرممکن است (مثلاً با کلیک روی دکمه). بنابراین برای دسترسی به کلیپ بورد کاربر در یک رویداد paste ، می توانید از API کلیپ بورد Async استفاده کنید و به 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.
      }
    }
  }
});

بیشتر خواندن

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

نسخه ی نمایشی

HTML

<!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>

CSS


        :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;
}
        

JS


        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);
};