Nowoczesny sposób
Korzystanie z interfejsu File handling API
Najpierw zadeklaruj atrybut file_handlers w manifeście aplikacji internetowej. Aby korzystać z interfejsu File handling API, musisz określić właściwość action (adres URL obsługi) i właściwości accept, która jest obiektem z typami MIME w postaci kluczy i tablic odpowiednich rozszerzeń plików.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
Następnie musisz użyć interfejsu File handling API, aby imperatycznie zająć się otwartymi plikami za pomocą 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.
}
});
}
Obsługa przeglądarek
- 102
- 102
- x
- x
Klasyczny sposób
Przy użyciu klasycznej metody DataTransferItem.getAsFile()
Jeśli interfejs File handling API nie jest obsługiwany, nadal możesz przeciągać i upuszczać pliki z eksploratora plików do aplikacji. Metoda DataTransferItem.getAsFile() zwraca obiekt File elementu danych przeciągania.
Jeśli element nie jest plikiem, ta metoda zwraca null. Możesz odczytać plik, ale nie możesz
do niego odpisać. Ta metoda ma tę wadę, że nie obsługuje katalogów.
Stopniowe ulepszanie
Poniższy fragment kodu korzysta z interfejsu File handling API, gdy jest dostępny, oraz dodatkowo rejestruje moduły obsługi przeciągania i upuszczania, aby umożliwić obsługę przeciąganych plików.
Zadeklaruj typy plików, które można obsługiwać w manifeście aplikacji internetowej. Przeglądarki, które nie obsługują tego interfejsu, zignorują go.
{
"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.
}
}
});
Więcej informacji
- Pozwól zainstalowanym aplikacjom internetowym jako modułami obsługi plików
- Interfejs File System Access API: upraszcza dostęp do plików lokalnych
Prezentacja
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}
`;
}
});
}