HTML5 [1] |
CSS3 [1] |
JavaScript [3] |
JS in HTML5 [4] |
Canvas (Context2D) [1] |
Canvas (WebGL) [0] |
Browser Technologies [2] |
jQuery [1] |
ExtJS [0] |
Prototype.js [2] |
SVG [2] |
Browsers [2] |
Mozilla Plugins
[0]
XUL, Jetpack, etc.
|
Web [2] |
MeowW [4] |
iOS [0] |
Алгоритмы [0] |
Криптография [0] |
Теория игр [0] |
Теория вероятностей [0] |
Математика [1] |
Мат. анализ [0] |
Алгебра [0] |
Дискретная математика [0] |
Теория графов [0] |
Комбинаторика [0] |
Теория чисел [0] |
Комплексный анализ [0] |
Матлогика
[0]
Математическая логика, её связь с теорией алгоритмов и т.п.
|
Тензоры [0] |
Геометрия [0] |
Топология [0] |
Дифференциальная геометрия [0] |
Дифференциальные уравнения [0] |
22:18:02 FileAPI - изучаем на практике |
Что такое FileAPI?Одной из задач спецификации HTML5 было представить веб-страничкам широкие возможности - такие как у программ. Конечно доступ к файлам дать не могли, это небезопасно: любая страница сможет украсть ценные данные с компьютера, либо поселить на компьютере вирус. Однако дали нечто похожее: мы можем выбрать файл на компьютере, и страница сможет его прочитать и получить данные о нём. Данная часть HTML5 носит название FileAPI. Вот о нём мы сегодня и поговорим. А из чего он состоит?Вообще говоря, под названием FileAPI можно объединить сразу три вещи - сам FileAPI, Drag&Drop, и наконец XMLHTTPRequest. FileAPI нам предоставляет возможность читать файлы, Drag&Drop позволяет читать файлы, перетащенные из проводника (или с рабочего стола), а XMLHTTPRequest 2 позволит нам отправлять файлы по AJAX. Давайте рассмотрим здесь все три. Кстати говоря, призвание Drag&Drop не только ловить перетащенные файлы. Изначально он был сделан для того, чтобы нативными средствами браузера осуществлять на странице перетаскивание. Как это делается, мы рассмотрим в другой статье. При чём тут файл-инпут?Свершилось! С помощью FileAPI мы можем прочитать файл, выбранный в файл-инпуте, не отходя от кассы. В смысле, не посылая на сервер. В FileAPI нам даётся пять классов: FileList, Blob, File, FileReader и FileError. Если не ошибаюсь, был ещё FileWriter. Сейчас нам нужен первый класс: FileList. Его мы получаем из свойства файл-инпута files, а затем работаем с ним как с обычным массивом. Вот например: Code <input type="file" onChange="alert(this.files[0]);"/> Забыл сказать: если кто не знает, при выборе файла образуется событие onChange. Итак, элементы массива files - объекты класса File. Мы можем установить у файл-инпута атрибут multiply для того, чтобы пользователь мог выбрать несколько файлов сразу. Ладно, класс File мы рассмотрим позже, а сейчас поговорим про Drag&Drop. Drag&Drop - перетащи и бросьМы можем перетащить на страницу файл (или несколько файлов) с рабочего стола или из проводника. Как например, перетаскиваешь картинку в Photoshop, и он её открывает. Вот так и страница может реагировать на перетаскивание файлов (нескольких!) или даже папки. Итак, при перетаскивании файла у нас образуется событие drop (от англ. drop - бросать). Если хотим ловить его всей страницей, присваиваем обработчик события тегу <body>; если же хотим ловить на какой-то элемент, присваиваем обработчик события ему. Итак, что же мы делаем в обработчике события drop? Вначале выполняем функции preventDefault() и stopPropagation() объекта event. Этим мы отменяем стандартную реакцию на событие drop, в результате чего браузер передумывает загружать перетащенный файл и отдаёт его странице. Далее мы получаем уже знакомую коллекцию FileList через свойство files объекта event.dataTransfer. Теперь пример: Code document.body.addEventListener('drop', function(e){ e.stopPropagation(); e.preventDefault(); alert(e.dataTransfer.files[0]); }); Классы Blob и File - свойства файлаИтак, откуда взять объект File - мы рассмотрели. Теперь подумаем, что с ним делать. Чтение файла рассмотрим позже, а пока рассмотрим сам класс. У него есть свойства:
Насколько мне известно, здесь Firefox выпендрился: у него есть свойства fileName и fileSize, аналогичные свойствам name и size. Кроме этого, в нём есть методы для чтения файлов (между тем, в спецификации ясно написано, что чтение должно производиться с помощью объекта FileReader):
Вот так вот. Если кто не знает, текстовые файлы - это те, которые можно открыть в блокноте и как-то отредактировать. Например, html. А бинарные - это которые открываешь в блокноте - а у тебя там куча непонятных символов в куче. Например, rar или psd. В принципе, можно прочитать бинарный файл как текстовый, а текстовый - как бинарный. Особой беды не будет, всё прочитается. Но - отличие этих методов в том, что в одном случае учитывается перевод строки (символ \n), а в другом - нет. Забыл пример: Code <input type="file" onChange="alert('Имя: '+this.files[0].name+'; MIME-тип: '+this.files[0].type+'; размер: '+this.files[0].size+' байт.');"/> FileReader - читаем файлыКак я уже сказал выше, читаются файлы через класс FileReader. Создаётся объект просто: Code var fr=new FileReader(); Сделано очень интереcно: мы можем одним объектом читать разные файлы. Рассмотрим функции, с помощью которых можно читать файлы:
Как мы здесь видим, для каждой функции надо передать объект File. Далее мы можем определить обработчики событий для FileReader. События можно определить через свойства с префиксом on, а можно и через функцию addEventListener. Список обработчиков:
Поехали дальше. У объекта FileReader есть свойство readyState, означающее стадию. Специально есть три константы:
Хорошо, все стадии и функции мы определили, что теперь? Метод readAsText вернёт нам значение файла? Как бы не так. Нам надо установить обработчик на onLoad, и получить значение свойства result объекта event.target.
Забыл: есть метод abort(), останавливающий и отменяющий чтение файла. Устанавливает свойство readyState в DONE, свойство event.target.result в null, вызывает обработчик события onError с ошибкой ABORT_ERR, затем onAbort, и наконец, onLoadEnd. Примера не будет. Ну и что, что тема огромная. Разберём оставшееся, затем дам огромный пример. FileError - ашипкаКласс FileError (плюс FileException) говорит нам, какая случилась ошибка (если она случается). Специально сделано несколько констант для идентификации ошибки.
XMLHTTPRequest 2Тут всё очень просто: у XMLHTTPRequest появился метод sendAsBinary, принимающий объект File. Code function startRead() { // obtain input element through DOM var file = document.getElementById('file').files[0]; if(file){ getAsText(file); } } function getAsText(readFile) { var reader = new FileReader(); // Read file into memory as UTF-16 reader.readAsText(readFile, "UTF-16"); // Handle progress, success, and errors reader.onprogress = updateProgress; reader.onload = loaded; reader.onerror = errorHandler; } function updateProgress(evt) { if (evt.lengthComputable) { // evt.loaded and evt.total are ProgressEvent properties var loaded = (evt.loaded / evt.total); if (loaded < 1) { // Increase the prog bar length // style.width = (loaded * 200) + "px"; } } } function loaded(evt) { // Obtain the read file data var fileString = evt.target.result; // Handle UTF-16 file dump if(utils.regexp.isChinese(fileString)) { //Chinese Characters + Name validation } else { // run other charset test } // xhr.send(fileString) } function errorHandler(evt) { if(evt.target.error.code == evt.target.error.NOT_READABLE_ERR) { // The file could not be read } } Забыл сказать: большинство функций наверняка можно эмулировать через Flash или Silverlight... |
|
Всего комментариев: 0 | |