Внешний предварительный просмотр изображения

JavaScript

Много раз у нас будут функциональные требования для загрузки изображения. Если мы сначала загрузим изображение на сервер, а затем отобразим возвращенный результат во внешнем интерфейсе, накладные расходы на производительность такой операции будут слишком высокими. Если изображений слишком много. , мы будем плакать Невообразимо столкнуться с ошибкой загрузки для удаления. Поэтому нам нужно сначала отобразить картинку на фронтенде, а затем пользователь подтвердит, что проблем нет, а затем загрузит ее единообразно, что идеально.

input

type=file

Я полагаю, что все знают, что для загрузки изображений на интерфейсе мы не можем обойтись без<input>Элемент ввода с type=file, который позволяет пользователю выбрать один или несколько файлов.

    <input type="file">

На этом этапе, когда мы нажимаем на элемент ввода, мы можем просмотреть локальный файл и выбрать загрузку. Однако на данный момент мы можем выбрать только один файл, а не несколько. тогда нужно<input>Еще один атрибут тегаmultiple

multiple

multiplaАтрибут позволяет пользователю выбрать несколько файлов, это атрибут, который не требует значения, то есть до тех пор, пока вашinputЕсли этот атрибут присутствует на этикетке, то независимо от его значения он будет поддерживать множественный выбор файлов. Вообще говоря, когда мы используем несколько, мы будем использовать только имя его атрибута, не добавляя к нему значение.

    <input type='file' multiple>

accept

Если вы попробуете указанные выше теги и атрибуты, вы обнаружите, что можете выбирать не только файлы изображений, но и различные другие файлы. Но в целом нам нужен только файл изображения, а в остальном можете делать все, что хотите, главное, чтобы вы не вылезали и не мешали мне. Итак, в настоящее время нам нужен атрибут accept для ограничения. Атрибут accept принимает разделенную запятыми строку типов MIME:

1. accept='image/png' 或者 accept='.png' --只接受 .png 格式的图片
2. accept='iamge/png,image/jpeg' 或者 accept='.png, .jpg .jpeg' 接受 .png .jpeg .jpg 格式的图片
3. accept='image/*' 接受所有类型的 image 


    <input type='file' multiple accetp='image/*'>

Примечание:'image/*' медленно отвечает в некоторых браузерах (браузеры Webkit, такие как Chrome и Safari), вместо этого вы можете использовать следующие методы.

    <<input type="file" multiple accept='image/png, image/jpeg, image/jpg, image/svg, image/gif'> 

стиль

Вообще говоря, мы установим вход наdisplay:none, а затем используйте метку, чтобы установить его стиль отображения

    // css

    input{
        display:none;
    }
    label{
        // 关于label样式
    }

    // html

    <input type='file' multiple accept='image/png, image/jpeg, image/jpg, image/svg, image/gif' id='inputFile'>
    <label for="inputFile">上传图片</label>

Объект FileList

Выбранный файл возвращает объект FileList через свойство HTMLInputElement.files, которое представляет собой список множества файловых файлов. Каждый файловый объект содержит следующую информацию:

1. name:文件名
2. lastModified:文件最后一次修改时间(时间戳形式)
3. lastModifiedDate:文件最后一次修改时间(UNIX timestamp形式)
4. size: 文件大小(byte 为单位)
5. type:文件 MIME 类型

Мы можем прослушивать событие изменения во входном теге:

    //  js

    document.getElementById('inputFile').addEventListener('change', changeHandler, false);

    function changeHandler(e) {
        var files = e.target.files;
        console.log(files) // 这里我们能获取到所选择的文件信息,需要注意的一点是 files 是个类数组对象。
    } 

FialeReader или URL объекта

Когда мы получаем файлы информации об объекте файла, как мы можем просмотреть его на странице, есть два метода: FileReader или URL-адрес объекта.
Как следует использовать эти два метода и в чем разница?

1. FileReader

FileReader реализует механизм асинхронного чтения. он должен пройтиFileReader()Конструктор создает экземпляр fileReader. Экземпляр реализует несколько методов и событий (частей):

  1. readerAsDataURL (файл): прочитайте файл и сохраните его в свойстве результата как URI данных.

  2. Событие загрузки: запускает событие загрузки после успешной загрузки файла.

  3. событие ошибки: запускает событие ошибки после того, как файл не загружается

  4. Событие прогресса: Событие прогресса запускается в процессе чтения файла. Это событие может быть аппроксимировано (запускается через определенные промежутки времени, а не в режиме реального времени) для отслеживания хода загрузки файла. Этот метод имеет три свойства: lengthComputable (доступна ли информация о ходе выполнения),loaded (сколько было загружено) и общая сумма.

usage:

    files.forEach(function(item) {
        var reader = new FileReader();
        reader.readAsDataURL(item);
        reader.onprogress = function(e) {
            if (e.lengthComputable) {
                // 简单把进度信息打印到控制台吧
                console.log(e.loaded / e.total + '%') 
            }
        }
        reader.onload = function(e) {
            var image = new Image()
            image.src = e.target.result
            body.appendChild(image)
        }
        reader.onerror = function(e) {
            console.log('there is an error!')
        }
    })

2. URL-адрес объекта

URL-адрес объекта относится к URL-адресу, который ссылается на данные, хранящиеся в файле или большом двоичном объекте. При использовании URL-адреса объекта вам не нужно сначала считывать данные в JavaScript, как FIleReader, он может ссылаться на URL-адрес в памяти и использовать его.

Метод создания URL-адреса объекта: window.URL.createObjectURL(). Совместимое написание:

    function creatObjectURL(file) {
        if (window.URL) {
            return window.URL.createObjectURL(file);
        } else if (window.webkitURL) {
            return window.webkitURL.createObjectURL(file);
        } else {
            return null
        }
    }

usage:

    files.forEach(function(item) {
        var url = createObjectURL(item)
        var image = new Image()
        image.src = url
        body.appendChild(image)
    })

разница:

См. (чжао) испытание (чао)

  1. FileReader — это асинхронная операция, а URL-адрес объекта — синхронная операция.

  2. FileReader.readAsDataURL возвращает файл с большим количеством байтовbase64Формат createObejctURL возвращает URL-адрес с хэшем.

  3. Из-за разных форм возврата FileReader.readerAsDataURL будет занимать больше памяти, но когда вы его больше не используете, он автоматически освободит память, в то время как createObjectURL может освободить память только тогда, когда ваша страница закрыта или revokeObejctURL вручную называется .

  4. С точки зрения совместимости: createObjectURL и FileReader.readerAsDataURL совместимы с IE10+ и всеми основными современными браузерами.

  5. createObjectURL более эффективен, чем FileReader.readerAsDataURL. Но если картинок много, лучше очистить память вручную, можно напрямую передать URL как параметр в window.URL.revokeObjectURL(). Совместимое написание:

     function revokeObjectURL(url) {
         if (widnow.URL) {
             return window.URL.revokeObjectURL(url)
         } else {
             return window.webkitURL.revokeObjectURL(url)
         }
     }

Простая реализация:

    // css

    input{
        display:none;
    }
    label{
        // 关于label样式
    }

    // html

    <input type='file' multiple accept='image/png, image/jpeg, image/jpg, image/svg, image/gif' id='inputFile'>
    <label for="inputFile">上传图片</label>

    // js 

    var inputFile = document.getElementById('inputFile')
    var body = document.body || document.getElementsByTagName('body')[0]

    inputFile.addEventListener('change', changeHandler, false)

    function changeHandler(e) {
        var files = Array.from(e.target.files)
        files.forEach(function(item) {
            var image = new Image()
            image.src = createObjectURL(item)
            body.appendChild(image)
            image.onload = function() {
                revokeObjectURL(this.src)
            }
        })
    }

    function createObjectURL(file) {
        if (window.URL) {
            return window.URL.createObjectURL(file)
        } else {
            return window.webkitURL.createObjectURL(file)
        }
    }

    function revokeObjectURL(file) {
        if (window.URL) {
            return window.URL.revokeObjectURL(file)
        } else {
            return window.webkitURL.revokeObjectURL(file)
        }
    }