Crea una interfaz Drag and Drop en HTML para subir archivos

30/08/2024 | CSS, HTML, JavaScript | 0 comentarios

Optimiza la experiencia del usuario en tu web con una interfaz drag and drop para subir archivos. Aprende cómo hacerlo con este tutorial práctico.

Descargar archivos Ver ejemplo


Crear una interfaz de usuario que permita arrastrar y soltar archivos para subirlos puede mejorar significativamente la experiencia del usuario en tu aplicación web. En este artículo, aprenderás cómo implementar esta funcionalidad utilizando HTML, CSS y JavaScript.

Drag & Drop

El estandar HTML define los eventos necesarios para poder arrastrar y soltar archivos, para ello se puede usar cualquier elemento HTML en donde se tienen disponibles los siguientes eventos:

  • dragstart: Se ejecuta sobre un elemento cuando se inicia una operación de arrastre.
  • dragover: Se activa cuando el mouse está sobre un elemento mientras se arrastra.
  • dragleave: Se activa cuando el mouse sale del elemento mientras se arrastra un archivo.
  • drop: Se dispara sobre el elemento en el que se terminó la operación de arrastre.

Para completar estas interfaces, luego del evento drop se tiene acceso a los archivos seleccionados en la propiedad e.dataTransfer.files


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

dropZone.addEventListener('dragover',  (e) => { /* dragover */ });
dropZone.addEventListener('dragleave', (e) => { /* dragleave */ });
dropZone.addEventListener('drop',      (e) => { console.log(e.dataTransfer.files); });

Drag & Drop Básico

Primero, necesitamos una estructura HTML básica. Crearemos un contenedor donde el usuario puede arrastrar y soltar los archivos.


<form method="post" action="#">
  <div class="drop-zone">
    <p>Arrastra y suelta tus archivos aquí</p>
  </div>
</form>

Para darle estilo al contenedor, crearemos estilos con un borde discontinuo, además de los estilos para cuando el archivo se encuentre encima del contenedor.


.drop-zone {
    width: 360px;
    height: 200px;
    border: 2px dashed #cccccc;
    border-radius: 10px;
    text-align: center;
    color: #cccccc;
    transition: border-color 0.3s;
}

.drop-zone.dragover {
    border-color: #666666;
}

.drop-zone p {
    margin: 52px 0 0 0;
}

Completamos el proceso creando nuestro script que detecte los eventos dragover, dragleave y drop para recibir los archivos y luego procesarlos.


document.addEventListener('DOMContentLoaded', () => {
    const dropZone = document.querySelector('.drop-zone');

    dropZone.addEventListener('dragover', (e) => {
        e.preventDefault();
        dropZone.classList.add('dragover');
    });

    dropZone.addEventListener('dragleave', () => {
        dropZone.classList.remove('dragover');
    });

    dropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        dropZone.classList.remove('dragover');
        handleFiles(e.dataTransfer.files);
    });

    function handleFiles(files) {
        const fileArray = Array.from(files);
        fileArray.forEach(file => {
            // submit data to server
            console.log('upload file: ' + file.name);
        });
    }
});

Pueden ver el resultado de este ejemplo en: drag-drop-file/basic.html

Drag & Drop Avanzado

Vamos a mejorar nuestra interfaz: sólo aceptaremos imágenes, agregaremos un botón para que el usuario pueda seleccionar archivos y finalmente agregaremos una previsualización de las imágenes seleccionadas.

Creamos el HTML donde agregamos un campo de tipo file que sólo acepta imágenes.


<form method="post" action="#">
  <div class="drop-zone">
    <p>Arrastra y suelta tus archivos aquí</p>
    <input type="file" id="photos" name="photos" multiple accept="image/*">
    <label for="photos">Seleccionar imágenes</label>
  </div>
</form>

Lo siguiente es agregar estilos para dar formato a la interfaz de upload.


.drop-zone {
    width: 360px;
    height: 200px;
    border: 2px dashed #cccccc;
    border-radius: 10px;
    text-align: center;
    color: #cccccc;
    transition: border-color 0.3s;
}

.drop-zone.dragover {
    border-color: #666666;
}

.drop-zone p {
    margin: 52px 0 0 0;
}

.drop-zone label {
    display: inline-block;
    padding: 8px 24px;
    background: #dd356e;
    cursor: pointer;
    border-radius: 5px;
    border: 1px solid #dd356e;
    color: white;
}

.drop-zone input[type=file] {
    display: none;
}

.gallery {
    padding: 16px;
}

.gallery img {
    width: 120px;
    margin: 0 10px 10px 0;
}

Completamos la tarea agregando el script, notar que usamos file.type.match para filtrar los archivos según el tipo y luego usamos la clase FileReader para leer los archivos antes de inyectarlo para previsualizar.


document.addEventListener('DOMContentLoaded', () => {
    const dropZone = document.querySelector('.drop-zone');
    const fileZone = document.getElementById('photos');

    dropZone.addEventListener('dragover', (e) => {
        e.preventDefault();
        dropZone.classList.add('dragover');
    });

    dropZone.addEventListener('dragleave', () => {
        dropZone.classList.remove('dragover');
    });

    dropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        dropZone.classList.remove('dragover');
        handleFiles(e.dataTransfer.files);
    });

    fileZone.addEventListener('change', (e) => {
        e.preventDefault();
        handleFiles(fileZone.files)
    });

    function handleFiles(files) {
        const fileArray = Array.from(files);
        fileArray.forEach(file => {
            if (file.type.match(/image.*/)) {
                uploadFile(file);
            }
        });
    }

    function uploadFile(file) {
        // preview image
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onloadend = function() {
            let img = document.createElement('img')
            img.src = reader.result;
            document.querySelector('.gallery').appendChild(img)
        }

        // submit data to server
        console.log('upload file: ' + file.name);
    }
});

Pueden ver el resultado de este ejemplo en: drag-drop-file/enhanced.html

Mejoras

Puedes mejorar esta interfaz con las siguientes opciones:

  • Validación de Archivos: Puedes añadir validación de archivos para verificar el tipo y tamaño antes de subirlos.
  • Progreso de Subida: Implementar una barra de progreso para que el usuario pueda ver el estado de la subida.
  • Eliminar Archivos: Agrega opciones para eliminar archivos seleccionados, esto por si el usuario se equivoca al seleccionar archivos.

Conclusión

Crear una interfaz drag and drop para subir archivos mejora la usabilidad de tu aplicación web. Con HTML, CSS y JavaScript, puedes implementar esta funcionalidad de manera efectiva. Además, puedes mejorar esta interfaz con validaciones adicionales, seguimiento del progreso y manejo de múltiples archivos según las necesidades de tu proyecto.

Referencias

Envíar Comentario

En este sitio los comentarios se publican previa aprobación del equipo de Kodetop. Evita los comentarios ofensivos, obscenos o publicitarios. Si deseas publicar código fuente puedes hacerlo entre las etiquedas <pre></pre>