Review the old and know the new

Traditionally, file uploads on the web are done using a file type form input box.

1
<input type="file">

We can specify the type of file to be selected with the accept property, the directory property specifies whether a folder can be selected, and the capture property specifies the front or rear camera.

It’s still very powerful.

But the file input box has the fatal disadvantage that the UI is too ugly and not customizable.

Although it is possible to simulate a button click using the <label> element and achieve a similar effect by pointing to the file input with the for attribute, it’s a bit more verbose.

So is there any way to click a normal button that also triggers a file selection? It would be nice to be able to set whether to select a folder or a file, and to set the type of file format to select.

There is really, the modern Web continues to develop, there is a new API called File System Access API, you can click on any element to trigger the file selection.

showOpenFilePicker method

Suppose there is a button on the page whose HTML looks like this.

1
<button id="button">Select image</button>

Then the following lines of JavaScript code will enable the file selection to appear when the button is clicked.

1
2
3
4
button.addEventListener('click', function () {
    // open file
    window.showOpenFilePicker();
});

It’s really simple, straightforward and straightforward.

Of course, we can also use the showDirectoryPicker() method to select folders.

1
2
3
4
button.addEventListener('click', function () {
    // Open folder
    window.showDirectoryPicker();
});

Since both API parameters and roles are similar, only the file selection is described in detail in this section.

Specification of file type, multiple choice or not

The showOpenFilePicker(options) method is parameter passable, and the specific parameters supported are as follows.

Among them, options is an optional parameter that supports the following properties.

multiple

Boolean value, default is false, means only one file can be selected.

excludeAcceptAllOption

Boolean value, the default is false, indicating whether to exclude all accept file types in the following types.

types

An array of selectable file types, each array item is also an object and supports the following two parameters.

  • description : Indicates the description of the file or folder, a string, optional.
  • accept : the accepted file type, object, and then the object key is the MIME match of the file, and the value is an array, indicating the supported file suffixes. The details can be schematically shown below.

For example, the following JS code is executed to select multiple local desktop images at once.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
window.showOpenFilePicker({
    types: [{
        description: 'Images',
        accept: {
            'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp']
        }
    }],
    // Multiple images can be selected
    multiple: true
});

Demo - Click the button to select and display multiple images

Above know the selection of the file, but how to deal with the selected file, the following is an example, it will be very helpful for you to learn.

The complete code is as follows.

1
2
<button id="button">Select image</button>
<p id="output"></p>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
button.addEventListener('click', async function () {
    // Open file
    const arrFileHandle = await window.showOpenFilePicker({
        types: [{
            accept: {
                'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp']
            }
        }],
        // Multiple images can be selected
        multiple: true
    });
    
    // Iterate through the selected files
    for (const fileHandle of arrFileHandle) {
        // Get file content
        const fileData = await fileHandle.getFile();
        // Read file data
        const buffer = await fileData.arrayBuffer();
        // Convert to Blod url address
        let src = URL.createObjectURL(new Blob([buffer]));
        // Show in the page
        output.insertAdjacentHTML('beforeend', `<img src="${src}">`);
    }
});

Select the corresponding image on your computer, for example, I have selected 2 nice PNG images:.

The result is a successful preview of the image effect on the web page, as shown in the following screenshot.

Isn’t it very similar to the traditional file selection.

Since these new APIs are all going Promise, you can use new JS syntax such as async and await to avoid all kinds of messy callbacks and make the code more concise and readable.

Isn’t that cool!

Unfortunately it’s a new API

For developers who don’t like HTML form elements and like JavaScript code to build everything, this API will be close and likeable, but, unfortunately, this API came out relatively new, late last year, and is not supported by the Safari browser, so it can’t be used directly.

However, there are quite a few projects that do a mix of processing, that is, they write a JS that uses the File System Access API for supported browsers and the traditional <input type="file"> for unsupported browsers, such as this project from Google Labs [browser-fs-access](https:// github.com/GoogleChromeLabs/browser-fs-access) However, there are quite a few projects that do a mix of processing, that is, they write a JS that uses the File System Access API for supported browsers and the traditional <input type="file"> for unsupported browsers, such as this project from Google Labs [browser-fs-access](https:// github.com/GoogleChromeLabs/browser-fs-access)

For file saving or downloading, try window.showSaveFilePicker() This API can sometimes be introduced, but of course, for actual development, file downloading is definitely using FileSaver.js It is very powerful and popular.

More details can be viewed https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API


Reference https://www.zhangxinxu.com/wordpress/2021/08/file-system-access-api/