Файловое поле обычно выглядит как кнопка с надписью вроде «Выберите файл», с информацией про выбранный файл рядом с ней.
>
>
> var input = document.querySelector("input");
> input.addEventListener("change", function() {
> if (input.files.length > 0) {
> var file = input.files[0];
> console.log("You chose", file.name);
> if (file.type)
> console.log("It has type", file.type);
> }
> });
>
Свойство >files элемента – массивоподобный объект (не настоящий массив), содержащий список выбранных файлов. Изначально он пуст. У элемента нет простого свойства >file, потому что пользователь может выбрать несколько файлов за раз при включённом атрибуте >multiple.
У объектов в свойстве >files есть свойства имя (имя файла), размер (размер файла в байтах), и тип (тип файла в смысле media type — >text/plain или >image/jpeg).
Чего у него нет, так это свойства, содержащего содержимое файла. Чтобы получить содержимое, приходиться постараться. Так как чтение файла с диска занимает длительное время, интерфейс должен быть асинхронным, чтобы документ не замирал. Конструктор >FileReader можно представлять себе, как конструктор >XMLHttpRequest, только для файлов.
Чтение файла происходит при помощи создания объекта >FileReader, регистрации события >“load” для него, и вызова его метода >readAsText с передачей тому файла. По окончанию загрузки в свойстве >result сохраняется содержимое файла.
Пример использует >Array.prototype.forEach для прохода по массиву, так как в обычном цикле было бы неудобно получать нужные объекты >file и >reader от обработчика событий. Переменные были бы общими для всех итераций цикла.
У >FileReaders также есть событие >“error”, когда чтение файла не получается. Объект >error будет сохранён в свойстве >error. Если вы не хотите забивать голову ещё одной неудобной асинхронной схемой, вы можете обернуть её в обещание (см. главу 17):