Книга: Выразительный JavaScript

Файловое поле

Файловое поле

Файловое поле изначально было предназначено для закачивания файлов с компьютера через форму. В современных браузерах они также позволяют читать файлы из JavaScript. Поле работает как охранник для файлов. Скрипт не может просто взять и открыть файл с компьютера пользователя, но если тот выбрал файл в этом поле, браузер разрешает скрипту начать чтение файла.

Файловое поле обычно выглядит как кнопка с надписью вроде «Выберите файл», с информацией про выбранный файл рядом с ней.

<input type="file">
<script>
  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);
    }
  });
</script>

Свойство files элемента – массивоподобный объект (не настоящий массив), содержащий список выбранных файлов. Изначально он пуст. У элемента нет простого свойства file, потому что пользователь может выбрать несколько файлов за раз при включённом атрибуте multiple.

У объектов в свойстве files есть свойства имя (имя файла), размер (размер файла в байтах), и тип (тип файла в смысле media type — text/plain или image/jpeg).

Чего у него нет, так это свойства, содержащего содержимое файла. Чтобы получить содержимое, приходиться постараться. Так как чтение файла с диска занимает длительное время, интерфейс должен быть асинхронным, чтобы документ не замирал. Конструктор FileReader можно представлять себе, как конструктор XMLHttpRequest, только для файлов.

<input type="file" multiple>
<script>
  var input = document.querySelector("input");
  input.addEventListener("change", function() {
    Array.prototype.forEach.call(input.files, function(file) {
      var reader = new FileReader();
      reader.addEventListener("load", function() {
        console.log("File", file.name, "starts with",
                    reader.result.slice(0, 20));
      });
      reader.readAsText(file);
    });
  });
</script>

Чтение файла происходит при помощи создания объекта FileReader, регистрации события “load” для него, и вызова его метода readAsText с передачей тому файла. По окончанию загрузки в свойстве result сохраняется содержимое файла.

Пример использует Array.prototype.forEach для прохода по массиву, так как в обычном цикле было бы неудобно получать нужные объекты file и reader от обработчика событий. Переменные были бы общими для всех итераций цикла.

У FileReaders также есть событие “error”, когда чтение файла не получается. Объект error будет сохранён в свойстве error. Если вы не хотите забивать голову ещё одной неудобной асинхронной схемой, вы можете обернуть её в обещание (см. главу 17):

function readFile(file) {
  return new Promise(function(succeed, fail) {
    var reader = new FileReader();
    reader.addEventListener("load", function() {
      succeed(reader.result);
    });
    reader.addEventListener("error", function() {
      fail(reader.error);
    });
    reader.readAsText(file);
  });
}

Возможно читать только часть файла, вызывая slice и передавая результат (т. н. объект blob) объекту reader.

Оглавление книги


Генерация: 1.438. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз