Il modo moderno
Utilizzo dell'API File Handling
Innanzitutto, dichiara l'attributo file_handlers
nel file manifest della tua app web. L'API File Gestione richiede di specificare la proprietà action
(un URL di gestione) e la proprietà accept
, che è un oggetto con tipi MIME come chiavi e array delle estensioni file corrispondenti.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
Successivamente, devi utilizzare l'API File handling per gestire in modo imperativo i file aperti tramite
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.
}
});
}
Supporto del browser
- 102
- 102
- x
- x
Il classico
Con il metodo DataTransferItem.getAsFile()
classico
Se l'API File Handling non è supportata, puoi comunque trascinare i file da Esplora file
all'app. Il metodo DataTransferItem.getAsFile()
restituisce l'oggetto File
dell'elemento di dati di trascinamento.
Se l'elemento non è un file, questo metodo restituisce null
. Anche se puoi leggere il file, non c'è modo di scrivere di nuovo. Questo metodo presenta lo svantaggio di non supportare le directory.
Miglioramento progressivo
Lo snippet riportato di seguito utilizza l'API File Handling, se disponibile, e registra inoltre i gestori di trascinamento per consentire la gestione dei file trascinati.
Dichiara i tipi di file che possono essere gestiti nel file manifest dell'app web. I browser che non supportano l'API File handling (API File handling) lo ignoreranno semplicemente.
{
"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.
}
}
});
Per approfondire
- Consentire alle applicazioni web installate di essere gestori di file
- API File System Access: semplifica l'accesso ai file locali
Demo
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}
`;
}
});
}