הסרת מחסומים באמצעות DataTransfer API

המשתמש יכול לשתף נתונים מעבר לחלון הדפדפן.

אולי שמעתם על את DataTransfer API, חלק מ API לגרירה ושחרור של HTML5 ואירועים בלוח העריכה. אפשר משמש להעברת נתונים בין היעדים המקוריים והיעדים המקבלים.

תמיכה בדפדפן

  • Chrome: 3.
  • קצה: 12.
  • Firefox: 3.5.
  • Safari: 4.

מקור

האינטראקציות של גרירה והעתקה-הדבקה משמשות בדרך כלל לאינטראקציות בתוך הדף להעביר טקסט פשוט מ-A ל-B. אבל מה שלרוב מתעלמים ממנו הוא היכולת להשתמש את אותן פעולות כדי לבצע פעולות מחוץ לחלון הדפדפן.

פעולות הגרירה והשחרור מובנות בדפדפן וגם האינטראקציות 'העתקה-הדבקה' יכולות לתקשר עם אפליקציות אחרות, באינטרנט או בכל דרך אחרת, והם לא קשורים למקור כלשהו. ה-API תומך בריבוי רשומות נתונים עם התנהגויות שונות בהתאם למקום שאליו הנתונים מועברים. שלך אפליקציית האינטרנט יכולה לשלוח ולקבל את הנתונים שהועברו בזמן ההאזנה לאירועים נכנסים.

היכולת הזו יכולה לשנות את הדרך שבה אנחנו חושבים על שיתוף ויכולת פעולה הדדית באינטרנט במחשב שולחני. לא נדרשת העברת נתונים בין אפליקציות יותר בשילובים הדוקים. במקום זאת, תוכלו לתת למשתמשים שליטה מלאה בהעברה לכל מקום שהם רוצים.

דוגמה לאינטראקציות אפשריות עם DataTransfer API. (הסרטון לא כולל אודיו).

העברת הנתונים מתבצעת

כדי להתחיל, צריך להטמיע גרירה של שחרור או העתקה-הדבקה. הדוגמאות שבהמשך מוצגות אינטראקציות של גרירה ושחרור, אבל תהליך ההעתקה וההדבקה דומה. אם המיקום שאתם לא מכירים את ממשק ה-API של 'גרירה ושחרור', יש מאמר מעולה הסבר על 'גרירה ושחרור' של HTML5, שמסביר את כל היתרונות.

באמצעות נתונים עם מפתח מסוג MIME, מאפשר לנהל אינטראקציה בחופשיות עם אפליקציות חיצוניות. רוב עורכי WYSIWYG, עורכי הטקסט והדפדפנים מגיבים בסוגי ה-mime שנעשה בהם שימוש לדוגמה.

document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
  event.dataTransfer.setData('text/plain', 'Foo bar');
  event.dataTransfer.setData('text/html', '<h1>Foo bar</h1>');
  event.dataTransfer.setData('text/uri-list', 'https://example.com');
});

שימו לב למאפיין event.dataTransfer. הפונקציה מחזירה מופע של DataTransfer בתור שתראו, לפעמים האובייקט הזה מוחזר על ידי מאפיינים עם שמות אחרים.

קבלת העברת הנתונים פועלת כמעט באופן דומה לקבלת ההעברה. להאזין לאירועים שהתקבלו (drop או paste) ולקרוא את המקשים. כשגוררים מעל רכיב, לדפדפן יש גישה רק למפתחות type של הנתונים. ניתן לגשת לנתונים עצמם רק לאחר ירידה בנתונים.

document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
  console.log(event.dataTransfer.types);
  // Without this, the drop event won't fire.
  event.preventDefault();
});

document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
  // Log all the transferred data items to the console.
  for (let type of event.dataTransfer.types) {
    console.log({ type, data: event.dataTransfer.getData(type) });
  }
  event.preventDefault();
});

יש תמיכה בשלושה סוגי MIME באפליקציות שונות:

  • text/html: מעבד את המטען הייעודי (payload) של HTML ברכיבי contentEditable ובפורמט עשיר עורכי טקסט (WYSIWYG) כמו Google Docs, Microsoft Word ועוד.
  • text/plain: הגדרת הערך של רכיבי הקלט, התוכן של עורכי הקוד והחלופה מ-text/html.
  • text/uri-list: מעבר לכתובת ה-URL עם שחרור הסמן בסרגל כתובות ה-URL או בדף הדפדפן. כתובת URL קיצור הדרך ייווצר כשתשחרר אותו בספרייה או בשולחן העבודה.

השימוש הנרחב של text/html על ידי עורכי WYSIWYG מועיל מאוד. כמו ב-HTML תוכלו להטמיע משאבים באמצעות כתובות URL של נתונים או באופן ציבורי כתובות URL נגישות. הוא מתאים גם לייצוא רכיבים חזותיים (לדוגמה: מלוח הציור) לעורכים כמו Google Docs

const redPixel = 'data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=';
const html = '<img src="' + redPixel + '" width="100" height="100" alt="" />';
event.dataTransfer.setData('text/html', html);

העברה באמצעות 'העתקה והדבקה'

בהמשך מוצג שימוש ב-DataTransfer API עם אינטראקציות של העתקה-הדבקה. שימו לב האובייקט DataTransfer מוחזר על ידי מאפיין שנקרא clipboardData עבור אירועים בלוח העריכה.

// Listen to copy-paste events on the document.
document.addEventListener('copy', (event) => {
  const copySource = document.querySelector('#copySource');
  // Only copy when the `activeElement` (i.e., focused element) is,
  // or is within, the `copySource` element.
  if (copySource.contains(document.activeElement)) {
    event.clipboardData.setData('text/plain', 'Foo bar');
    event.preventDefault();
  }
});

document.addEventListener('paste', (event) => {
  const pasteTarget = document.querySelector('#pasteTarget');
  if (pasteTarget.contains(document.activeElement)) {
    const data = event.clipboardData.getData('text/plain');
    console.log(data);
  }
});

פורמטים מותאמים אישית של נתונים

אתם לא מוגבלים לסוגי ה-MIME הראשוניים, אבל אפשר להשתמש בכל מפתח כדי לזהות את הרכיבים שהועברו . זה יכול להיות שימושי לאינטראקציות בין דפדפנים בתוך האפליקציה שלך. כפי שמוצג בהמשך, יכול להעביר נתונים מורכבים יותר באמצעות הפונקציות JSON.stringify() ו-JSON.parse().

document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
  const data = { foo: 'bar' };
  event.dataTransfer.setData('my-custom-type', JSON.stringify(data));
});

document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
  // Only allow dropping when our custom data is available.
  if (event.dataTransfer.types.includes('my-custom-type')) {
    event.preventDefault();
  }
});

document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
  if (event.dataTransfer.types.includes('my-custom-type')) {
    event.preventDefault();
    const dataString = event.dataTransfer.getData('my-custom-type');
    const data = JSON.parse(dataString);
    console.log(data);
  }
});

חיבור לאינטרנט

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

תקן JSON-LD (נתונים מקושרים) הוא שיטה טובה לכך. זה כן קל לקריאה ולכתיבה ב-JavaScript. Schema.org מכיל הרבה סוגים מוגדרים מראש שאפשר להשתמש בהם, ואפשר גם להשתמש בהגדרות סכימה מותאמות אישית.

const data = {
  '@context': 'https://schema.org',
  '@type': 'ImageObject',
  contentLocation: 'Venice, Italy',
  contentUrl: 'venice.jpg',
  datePublished: '2010-08-08',
  description: 'I took this picture during our honey moon.',
  name: 'Canal in Venice',
};
event.dataTransfer.setData('application/ld+json', JSON.stringify(data));

כשמשתמשים בסוגי Schema.org, אפשר להתחיל בסוג Thing הכללי, או להשתמש במשהו שקרוב יותר לתרחיש לדוגמה שלכם, כמו Event, אדם, MediaObject, מקום, או אפילו סוגים ספציפיים מאוד כמו MedicalEntity במקרה הצורך. כשמשתמשים ב-TypeScript, אפשר להשתמש הגדרות הממשק מהגדרות הסוגים schema-dts.

שידור וקבלה של נתוני JSON-LD מאפשרים לכם לתמוך באינטרנט פתוח ומחובר יותר. ב- שדוברים את אותה שפה, תוכלו ליצור שילובים עמוקים עם גורמים חיצוניים תרגום מכונה. אין צורך בשילובים מורכבים של ממשקי API. כל המידע הנדרש נכללות בנתונים שהועברו.

חשוב על כל האפשרויות להעברת נתונים בין כל אפליקציית (אינטרנט) ללא הגבלות: שיתוף אירועים מהיומן לאפליקציית ToDo המועדפת עליכם, צירוף קבצים וירטואליים אל אימיילים, שיתוף אנשי קשר. זה יהיה מעולה, נכון? השלב הזה מתחיל בך! 🙌

חששות

ה-DataTransfer API זמין כיום, אבל יש כמה דברים שכדאי לדעת לפני השילוב.

תאימות דפדפן

כולם דפדפני מחשב תומכים בשיטה שתוארו למעלה, בעוד שמכשירים ניידים תומכים בהם. לא. השיטה נבדקה בכל הדפדפנים המובילים (Chrome, Edge, Firefox, Safari) במערכות ההפעלה (Android, ChromeOS, iOS, macOS, Ubuntu Linux ו-Windows), אבל לצערנו גם ב-Android ו-iOS לא עברו את הבדיקה. הדפדפנים ממשיכים להתפתח, אבל כרגע השיטה מוגבלת לדפדפנים במחשב בלבד.

יכולת גילוי

גרירה והעתקה והדבקה הן אינטראקציות ברמת המערכת כשעובדים על מחשב שולחני, עם מגיעים לממשקי ה-GUI הראשונים לפני יותר מ-40 שנה. תחשבו כמה פעמים השתמשו באינטראקציות האלה לארגון קבצים. המצב הזה עדיין לא נפוץ באינטרנט.

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

נגישות

גרירה ושחרור אינה אינטראקציה נגישה במיוחד, אבל ממשק ה-API של DataTransfer פועל גם עם העתקה-הדבקה. הקפידו להאזין לאירועים מסוג 'העתקה-הדבקה'. לא נדרשת הרבה עבודה נוספת, והמשתמשים תודה שהוספת אותו.

אבטחה ופרטיות

יש כמה שיקולי אבטחה ופרטיות שצריך לשים לב אליהם כשמשתמשים בשיטה הזו.

  • נתוני הלוח זמינים לאפליקציות אחרות במכשיר של המשתמש.
  • לאפליקציות אינטרנט שגוררים יש גישה למקשי הסוג, ולא לנתונים. הנתונים בלבד יהיה זמין לאחר שחרור או הדבקה.
  • יש להתייחס לנתונים שמתקבלים כמו לכל קלט אחר של משתמשים; חיטוי ואמתו לפני השימוש.

תחילת העבודה עם ספריית העזרה של Transmat

האם אתם מעוניינים להשתמש ב-DataTransfer API באפליקציה שלכם? כדאי לעיין ספריית ההעברות ב-GitHub ספריית הקוד הפתוח הזו מתאימה לדפדפן מספקות כלי עזר של JSON-LD, ומכיל צופה שמגיב לאירועי העברה הדגשת אזורים משוחררים ואפשרות לשלב את פעולות העברת הנתונים בין גרירה ושחרור קיימים בפועל.

import { Transmat, TransmatObserver, addListeners } from 'transmat';

// Send data on drag/copy.
addListeners(myElement, 'transmit', (event) => {
  const transmat = new Transmat(event);
  transmat.setData({
    'text/plain': 'Foobar',
    'application/json': { foo: 'bar' },
  });
});

// Receive data on drop/paste.
addListeners(myElement, 'receive', (event) => {
  const transmat = new Transmat(event);
  if (transmat.hasType('application/json') && transmat.accept()) {
    const data = JSON.parse(transmat.getData('application/json'));
  }
});

// Observe transfer events and highlight drop areas.
const obs = new TransmatObserver((entries) => {
  for (const entry of entries) {
    const transmat = new Transmat(entry.event);
    if (transmat.hasMimeType('application/json')) {
      entry.target.classList.toggle('drag-over', entry.isTarget);
      entry.target.classList.toggle('drag-active', entry.isActive);
    }
  }
});
obs.observe(myElement);

אישורים

תמונה ראשית (Hero) מאת Luba Ertel מופעלת ביטול הפתיחה.