x
 
Константин Дунаев
13 августа 2020
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Как сделать всю страницу полем для загрузки файла по методике дрэг энд дроп, а не только в какую-то размеченную область на странице?


Константин!

Один из спо­со­бов — зафик­си­ро­вать и рас­тя­нуть область для загрузки файла на всё окно. Чтобы она не пере­кры­вала всю стра­ницу, можно скрыть её с помо­щью display: none, а пока­зы­вать только при пере­тас­ки­ва­нии файлов:

#dropZone {
  display: none;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1000; // Нужно поста­вить такой z-index, чтобы поле было самым верх­ним слоем
}

#dropZone.visible { display: block; }

Для этого доба­вим к доку­менту обра­бот­чики собы­тий dragenter и dragover:

const dropZone = document.getElementById('dropZone');

function showDropZone(e) { dropZone.classList.add('visible'); }

['dragenter', 'dragover'].forEach(event => { document.addEventListener(event, showDropZone, false); });

Область загрузки нужно скры­вать, если кур­сор с пере­тя­ги­ва­е­мыми фай­лами увели за пре­делы обла­сти, или «бро­сили» файлы в области:

function hideDropZone(e) {
  dropZone.classList.remove('visible');
}

['dragleave', 'drop'].forEach(event => { dropZone.addEventListener(event, hideDropZone, false); });

Чтобы бра­у­зер не откры­вал пере­тас­ки­ва­е­мые файлы и обра­ба­ты­вал собы­тия кор­ректно, забло­ки­руем дефолт­ную обра­ботку собы­тий, свя­зан­ных с перетаскиванием:

function preventDefaults(e) {
  e.preventDefault();
  e.stopPropagation();
}

['dragenter', 'dragleave', 'dragover', 'drop'].forEach(event => { dropZone.addEventListener(event, preventDefaults, false); });

Для полу­че­ния содер­жи­мого фай­лов, исполь­зуем свой­ство dataTransfer собы­тия drop. Оно воз­вра­щает объ­ект DataTransfer с файлами:

dropZone.addEventListener('drop', handleDrop, false);

function handleDrop(e) { const files = e.dataTransfer.files handleFiles(files) }

Ну а дальше загру­жаем файлы на сервер:

function handleFiles(files) {
  ([...files]).forEach(uploadFile)
}

function uploadFile(file) { const url = 'http://mysite.com/api';

  // Создаем объ­ект дан­ных формы FormData const formData = new FormData();

  // При­со­еди­няем к дан­ным формы файл formData.append('file', file);

// Отправ­ляем дан­ные формы на сер­вер fetch(url, { method: 'POST', body: formData }) .then(() => { // Успеш­ная загрузка }) .catch((e) => { // Обра­ботка ошибки }); }

Весь код пол­но­стью можно посмот­реть в Код­сэнд­боксе. Попро­буйте пере­тя­нуть файлы в область с браузером.

Что ещё посмотреть

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Поделиться
Отправить

Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

Как бороться с багами? Часть десятая: не утонуть в багах и глюках Как организовать процесс сдачи задачи и код-ревью в рамках спринта? Типовые решения в вёрстке. Как форматировать ХТМЛ 9 Что нужно, чтобы сайт на Айфоне выглядел также как на Андроиде, а не в два раза меньше? 1




Недавно всплыло

Что лучше использовать: спинер или прогрессбар? 5 5 Продолжение совета о системной фотосъёмке пластинок, часть 4 1 7