העתקת טקסט ותמונות ל Clipboard מתוך JavaScript

12/12/2024

הממשק navigator.clipboard מאפשר לנו להעתיק דברים ל Clipboard באפליקציית ווב מתוך קוד JavaScript והאמת שהעבודה איתו הפתיעה אותי לטובה. הנה שתי דוגמאות וכמה טיפים על דברים שיכולים להסתבך.

1. העתקת טקסט מהקוד ל Clipboard

אם אתם צריכים לבנות כפתור "העתק ל Clipboard" או סתם לדחוף לאנשים ל Clipboard דברים בלי שהם יבקשו תשמחו לשמוע שכל הסיפור הוא בסך הכל קריאת פונקציה אחת: navigator.clipboard.writeText. לדוגמה אם יש לי אלמנט input בעמוד הקוד הבא יגרום לכל שינוי של הטקסט ב input להיות מועתק אוטומטית ל Clipboard של המשתמש כדי שיהיה קל להדביק את זה במקומות אחרים:

input.addEventListener('input', async (ev) => {
  navigator.clipboard.writeText(ev.target.value);
});

2. העתקת תמונה מהקוד ל Clipboard

העסק קצת מסתבך כשעוברים לדבר על העתקת דברים מסוגים שונים. ה Clipboard תומך במגוון של פריטים ובכתיבה אליו אנחנו יכולים להעביר את "סוג המידע" בצירוף הביטים של המידע והכל יעבוד. האתגר מתוך JavaScript הוא שלא תמיד קל לנו להגיע למידע.

ניקח לדוגמה העתקה של תמונה מאלמנט img ל Clipboard של המשתמש. בשביל להגיע לביטים של התמונה אנחנו צריכים שהתמונה תיטען מהדומיין שלנו או מדומיין שמאפשר גישה לביטים באמצעות כותרות CORS. אפילו אם נעשה את זה צריך לשים לב שלא כל מערכות ההפעלה תומכות בכל סוגי התמונות ולדוגמה אצלי במק לא הצלחתי להעתיק JPEG ל Clipboard אלא רק png.

אם אנחנו מוכנים לחיות עם המגבלות הקוד כדי להעתיק תמונה ל Clipboard הוא (באדיבות ChatGPT):

async function copyImageFromImgElement() {
  const img = document.getElementById('image-to-copy');

  // Ensure that the image is fully loaded and the src attribute is set
  if (!img.complete || !img.src) {
    console.error('Image not fully loaded or missing src attribute.');
    return;
  }

  try {
    // Fetch the image as a blob
    const response = await fetch(img.src);
    const blob = await response.blob();

    // Create a ClipboardItem using the image blob
    const clipboardItem = new ClipboardItem({ [blob.type]: blob });

    // Write the ClipboardItem to the system clipboard
    await navigator.clipboard.write([clipboardItem]);

    console.log('Image copied to clipboard successfully!');
  } catch (err) {
    console.error('Failed to copy image:', err);
  }
}

בגישה זאת אנחנו מושכים את התמונה עם fetch כדי לקבל את הביטים שלה, ואז כותבים את הביטים בצירוף סוג התמונה ל Clipboard.

גישה נוספת קצת יותר יעילה אבל גם עם קצת יותר קוד היא לקחת את התמונה הקיימת ולכתוב אותה לתוך Canvas. אחרי זה אפשר להעתיק מה Canvas את הביטים של התמונה ולהעתיק אותם ל Clipboard. זה הקוד, שוב באדיבות ChatGPT:

async function copyImageFromCanvas() {
  const img = document.getElementById('image-to-copy');

  // Ensure the image is loaded
  if (!img.complete || !img.naturalWidth) {
    console.error('Image not fully loaded or invalid.');
    return;
  }

  // Create a canvas element
  const canvas = document.createElement('canvas');
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  const ctx = canvas.getContext('2d');

  // Draw the image onto the canvas
  ctx.drawImage(img, 0, 0);

  // Convert the canvas content to a Blob
  canvas.toBlob(async (blob) => {
    if (!blob) {
      console.error('Failed to create blob from canvas.');
      return;
    }

    try {
      // Create a ClipboardItem
      const clipboardItem = new ClipboardItem({ [blob.type]: blob });

      // Write it to the clipboard
      await navigator.clipboard.write([clipboardItem]);
      console.log('Image copied to clipboard successfully from canvas!');
    } catch (err) {
      console.error('Failed to copy image from canvas:', err);
    }
  }, 'image/png'); // second parameter is optional; 'image/png' is default
}