Cara modern
Menggunakan File Handling API
Pertama, deklarasikan atribut file_handlers
di manifes aplikasi web Anda. File Handling API mengharuskan Anda menentukan properti action
(URL penanganan) dan properti accept
, yang merupakan objek dengan jenis MIME sebagai kunci dan array dari ekstensi file yang terkait secara khusus.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
Selanjutnya, Anda harus menggunakan File Handling API untuk secara imperatif menangani file yang terbuka melalui
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.
}
});
}
Dukungan Browser
- 102
- 102
- x
- x
Cara klasik
Menggunakan metode DataTransferItem.getAsFile()
klasik
Jika File Handling API tidak didukung, Anda tetap dapat menarik lalu melepas file dari file explorer
ke dalam aplikasi. Metode DataTransferItem.getAsFile()
akan menampilkan objek File
item data tarik.
Jika item bukan file, metode ini akan menampilkan null
. Meskipun Anda dapat membaca file itu, tidak ada cara untuk membalasnya. Metode ini memiliki kekurangan, yaitu tidak mendukung direktori.
{i>Progressive enhancement <i}
Cuplikan di bawah ini menggunakan File Handling API jika tersedia, dan juga mendaftarkan pengendali tarik lalu lepas agar file yang ditarik dapat ditangani.
Mendeklarasikan jenis file yang dapat ditangani dalam manifes aplikasi web. Browser yang tidak mendukung File Handling API akan mengabaikan ini.
{
"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.
}
}
});
Bacaan lebih lanjut
- Mengizinkan aplikasi web terinstal menjadi pengendali file
- File System Access API: menyederhanakan akses ke file lokal
Demo
<!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>
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;
}
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}
`;
}
});
}