كيفية التعامل مع الملفات المفتوحة من مستكشف الملفات

بالانس لياو
بالانسجام لياو

الطريقة الحديثة

استخدام واجهة برمجة تطبيقات معالجة الملفات

يجب أولاً تحديد السمة file_handlers في بيان تطبيق الويب. تتطلّب واجهة برمجة تطبيقات معالجة الملفات تحديد السمة action (عنوان URL للمعالجة) والسمة accept، وهي كائن يتضمّن أنواع MIME كمفاتيح ومصفوفات من امتدادات الملفات المقابلة بشكل خاص.

{
  "file_handlers": [
    {
      "action": "./",
      "accept": {
        "image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
      }
    }
  ]
}

بعد ذلك، عليك استخدام واجهة برمجة التطبيقات File Handling API للتعامل بشكل أساسي مع الملفات المفتوحة من خلال launchQueue.

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    for (const fileHandle of launchParams.files) {
      // Handle the file.
    }
  });
}

التوافق مع المتصفح

  • 102
  • 102
  • x
  • x

الطريقة الكلاسيكية

استخدام طريقة DataTransferItem.getAsFile() الكلاسيكية

إذا لم تكن واجهة برمجة تطبيقات معالجة الملفات غير متاحة، يظل بإمكانك سحب الملفات وإفلاتها من مستكشف الملفات في التطبيق. تعرض طريقة DataTransferItem.getAsFile() الكائن File لعنصر بيانات السحب. إذا لم يكن العنصر ملفًا، ستعرض هذه الطريقة القيمة null. بينما يمكنك قراءة الملف، لا توجد طريقة للرد عليه. لهذه الطريقة عيب أنها لا تدعم الأدلة.

التوافق مع المتصفح

  • 11
  • 12
  • 50
  • 5.1

المصدر

التحسين التدريجي

يستخدم المقتطف أدناه واجهة برمجة تطبيقات معالجة الملفات عندما تكون متاحة، كما يسجِّل أيضًا معالجات السحب والإفلات حتى يمكن التعامل مع الملفات التي يتم سحبها.

يُرجى تحديد أنواع الملفات التي يمكن معالجتها في بيان تطبيق الويب. ستتجاهل المتصفحات التي لا تدعم File Handling API هذا.

{
  "file_handlers": [
    {
      "action": "./",
      "accept": {
        "image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
      }
    }
  ]
}
// File Handling API
const handleLaunchFiles = () => {
  window.launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    launchParams.files.forEach(async (handle) => {
      const file = await handle.getFile();
      console.log(`File: ${file.name}`);
      // Do something with the file.
    });
  });
};

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  handleLaunchFiles();
}

// This is the drag and drop zone.
const elem = document.querySelector('main');
// Prevent navigation.
elem.addEventListener('dragover', (e) => {
  e.preventDefault();
});
// Visually highlight the drop zone.
elem.addEventListener('dragenter', (e) => {
  elem.style.outline = 'solid red 1px';
});
// Visually unhighlight the drop zone.
elem.addEventListener('dragleave', (e) => {
  elem.style.outline = '';
});
// This is where the drop is handled.
elem.addEventListener('drop', async (e) => {
  // Prevent navigation.
  e.preventDefault();
  // Unhighlight the drop zone.
  elem.style.outline = '';
  // Prepare an array of promises…
  const fileHandlesPromises = [...e.dataTransfer.items]
    // …by including only files (where file misleadingly means actual file _or_
    // directory)…
    .filter((item) => item.kind === 'file')
    // …and, depending on previous feature detection…
    .map((item) => item.getAsFile());
  // Loop over the array of promises.
  for await (const handle of fileHandlesPromises) {
    // This is where we can actually exclusively act on the files.
    if (handle.isFile) {
      console.log(`File: ${handle.name}`);
      // Do something with the file.
    }
  }
});

قراءات إضافية

الإصدار التجريبي

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="manifest" href="manifest.json" />
    <title>How to handle files opened from the file explorer</title>
    <link rel="stylesheet" href="style.css" />
    <!-- TODO: Devsite - Removed inline handlers -->
    <!-- <script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', async () => {
          const registration = await navigator.serviceWorker.register(
            'sw.js',
          );
          console.log(
            'Service worker registered for scope',
            registration.scope,
          );
        });
      }
    </script>
    <script src="script.js" type="module"></script> -->
  </head>
  <body>
    <h1>How to handle files opened from the file explorer</h1>
    <p>Install the app. After the installation, try opening an image file from the file explorer with the app.
  </body>
</html>

CSS


        html {
  box-sizing: border-box;
  font-family: system-ui, sans-serif;
  color-scheme: dark light;
}

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

body {
  margin: 1rem;
}

img {
  height: auto;
  max-width: 100%;
  display: block;
}
        

JS


        if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    for (const fileHandle of launchParams.files) {
      document.body.innerHTML += `

${fileHandle.name}

`; } }); }