Загрузка файлов

Библиотека Cash представляет собой легковесный аналог jQuery, ориентированный на работу с DOM и асинхронными операциями. Она обеспечивает удобный API для манипуляции элементами страницы, в том числе для загрузки и обработки файлов. В отличие от более тяжёлого jQuery, Cash минимизирует объём кода, сохраняя при этом привычный синтаксис для выборки элементов и привязки событий.

Выбор элементов и привязка событий

Для работы с загрузкой файлов необходимо понимать, как Cash обрабатывает элементы <input type="file">. Для выбора элемента используется стандартный синтаксис:

const fileInput = $('#fileInput');

fileInput становится объектом Cash, на котором можно вызывать методы библиотеки. Основной метод для обработки событий — .on():

fileInput.on('change', (event) => {
    const files = event.target.files;
    console.log(files);
});

Ключевой момент: event.target.files возвращает FileList, который ведёт себя как массив и содержит все выбранные пользователем файлы.

Асинхронная загрузка файлов

Cash не предоставляет собственного AJAX API, но можно использовать стандартный fetch или XMLHttpRequest. Для отправки файлов применяется объект FormData, который позволяет инкапсулировать данные файлов и другие поля формы.

const uploadFiles = (files) => {
    const formData = new FormData();
    Array.from(files).forEach((file) => {
        formData.append('files[]', file);
    });

    fetch('/upload', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log('Успешно загружено', data))
    .catch(error => console.error('Ошибка загрузки', error));
};

fileInput.on('change', (event) => {
    uploadFiles(event.target.files);
});

Выделение ключевых аспектов:

  • FormData.append позволяет добавлять несколько файлов под одним ключом.
  • fetch автоматически устанавливает заголовки для multipart/form-data.
  • Обработка ошибок должна учитывать сетевые сбои и некорректные форматы файлов.

Фильтрация и валидация файлов

Перед загрузкой рекомендуется проверять файлы по типу и размеру:

const validateFiles = (files, maxSize = 2 * 1024 * 1024, allowedTypes = ['image/jpeg', 'image/png']) => {
    return Array.from(files).filter(file => 
        allowedTypes.includes(file.type) && file.size <= maxSize
    );
};

fileInput.on('change', (event) => {
    const validFiles = validateFiles(event.target.files);
    if (validFiles.length) {
        uploadFiles(validFiles);
    } else {
        console.warn('Файлы не соответствуют требованиям');
    }
});

Важные моменты:

  • Проверка типов файлов помогает предотвратить загрузку неподдерживаемых форматов.
  • Ограничение размера защищает сервер и клиент от чрезмерных данных.

Отображение прогресса загрузки

Для улучшения пользовательского опыта используется событие progress объекта XMLHttpRequest. Cash облегчает привязку событий, но прогресс отслеживается стандартным способом:

const uploadWithProgress = (files) => {
    const formData = new FormData();
    Array.from(files).forEach(file => formData.append('files[]', file));

    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload');

    xhr.upload.onprogr ess = (event) => {
        if (event.lengthComputable) {
            const percent = (event.loaded / event.total) * 100;
            console.log(`Загружено ${percent.toFixed(2)}%`);
        }
    };

    xhr.onl oad = () => {
        if (xhr.status === 200) {
            console.log('Загрузка завершена', JSON.parse(xhr.responseText));
        } else {
            console.error('Ошибка сервера', xhr.status);
        }
    };

    xhr.send(formData);
};

fileInput.on('change', (event) => {
    uploadWithProgress(event.target.files);
});

Ключевые особенности:

  • xhr.upload.onprogress отличается от обычного xhr.onprogress и используется именно для отслеживания прогресса отправки данных.
  • Использование toFixed(2) обеспечивает аккуратное отображение процента.
  • Обработка ошибок сервера и сети должна быть разделена.

Динамическая работа с несколькими элементами

Cash позволяет обрабатывать сразу несколько элементов выбора файлов:

$$('.file-input').on('change', (event) => {
    const files = event.target.files;
    uploadFiles(files);
});

Использование $$ возвращает массив элементов Cash, что удобно при работе с динамическими формами. Это особенно полезно для форм с повторяющимися полями или при динамическом добавлении элементов через JS.

Работа с предварительным просмотром файлов

Для изображений часто требуется показать миниатюру до загрузки:

const previewImages = (files, container) => {
    container.innerHTML = '';
    Array.from(files).forEach(file => {
        if (file.type.startsWith('image/')) {
            const reader = new FileReader();
            reader.onl oad = (e) => {
                const img = document.createElement('img');
                img.src = e.target.result;
                img.width = 100;
                container.appendChild(img);
            };
            reader.readAsDataURL(file);
        }
    });
};

fileInput.on('change', (event) => {
    previewImages(event.target.files, document.getElementById('preview'));
});

Особенности:

  • FileReader.readAsDataURL конвертирует файл в base64, удобный для отображения на клиенте.
  • Можно комбинировать с фильтрацией по типу и размеру.

Совместное использование с другими библиотеками

Cash легко интегрируется с другими инструментами:

  • Axios для более удобного API POST с файлами.
  • Lodash для работы с массивами файлов (например, сортировка, уникализация).
  • SweetAlert или кастомные уведомления для отображения статуса загрузки.

Благодаря совместимости с нативными API, Cash выступает только как лёгкий слой для работы с DOM и событиями, не ограничивая использование современных методов загрузки и асинхронной обработки.