I’m implementing a drag&drop in JS, it works but the detection of my file is quite bad (when the file is drag over the dropzone it isn’t always detected).
Also i would like to click anywhere in the dropzone to activate my input it doesn’t work either.
Here is my code and a link of my codePen to test it: https://codepen.io/ChloeMarieDom/pen/QWPLqNz?editors=0010)
<div class="frame">
<div class="container">
<div class="title">Drop file to upload</div>
<div class="line"></div>
<div class="dropzone">
<svg class="upload" viewBox="0 0 640 512" width="100" title="cloud-upload-alt">
<path d="M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zM393.4 288H328v112c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V288h-65.4c-14.3 0-21.4-17.2-11.3-27.3l105.4-105.4c6.2-6.2 16.4-6.2 22.6 0l105.4 105.4c10.1 10.1 2.9 27.3-11.3 27.3z" />
</svg>
<span class="filename"></span>
<input type="file" class="input">
</div>
<div class="upload-btn">Upload file</div>
<svg class="syncing" viewBox="0 0 512 512" width="100" title="circle-notch">
<path d="M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z" />
</svg>
<svg class="done" viewBox="0 0 512 512" width="100" title="check-circle">
<path d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z" />
</svg>
</div>
</div>
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400);
.frame {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
background:linear-gradient(to top right, #3A92AF 0%, #5CA05A 100%);
color: #676767;
font-family: 'Open Sans', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.container {
position: absolute;
width: 300px;
height: 260px;
background: #fff;
border-radius: 3px;
box-shadow: 8px 10px 15px 0 rgba(0,0,0,0.2);
}
.title {
position: absolute;
top: 0;
width: 100%;
font-size: 16px;
text-align: center;
border-bottom: 1px solid #676767;
line-height: 50px;
}
.line {
position: relative;
width: 0px;
height: 3px;
top: 49px;
left: 0;
background: #6ECE3B;
&.active {
animation: progressFill 5s ease-out forwards;
}
}
@keyframes progressFill {
from {
width: 0;
}
to {
width: 100%;
}
}
.dropzone {
visibility: show;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100px;
height: 80px;
border: 1px dashed #676767;
border-radius: 3px;
}
.dropzone.dragover {
background-color: rgba(0, 0, 0, 0.1);
}
.upload {
position: absolute;
width: 60px;
opacity: 0.3;
}
.input {
position: absolute;
inset: 0;
opacity: 0;
}
.filename {
overflow: hidden;
}
.syncing {
opacity: 0;
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 25px);
width: 50px;
height: 50px;
animation: rotate 2s linear infinite;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.done {
opacity: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 50px;
height: 50px;
}
.upload-btn {
position: relative;
top: 180px;
left: 80px;
width: 140px;
height: 40px;
line-height: 40px;
text-align: center;
background: #6ECE3B;
border-radius: 3px;
cursor: pointer;
color: #fff;
font-size: 14px;
box-shadow: 0 2px 0 0 #498C25;
transition: all .2s ease-in-out;
&:hover {
box-shadow: 0 2px 0 0 #498C25, 0 2px 10px 0 #6ECE3B;
}
}
// Variables
const dropzone = document.querySelector('.dropzone');
const filenameDisplay = document.querySelector('.filename');
const input = document.querySelector('.input');
const uploadBtn = document.querySelector('.upload-btn');
const syncing = document.querySelector('.syncing');
const done = document.querySelector('.done');
const upload = document.querySelector('.upload');
const line = document.querySelector('.line');
dropzone.addEventListener("dragover", (e) => {
e.preventDefault();
e.stopPropagation();
dropzone.classList.add("dragover");
});
dropzone.addEventListener("dragleave", () => {
dropzone.classList.remove("dragover");
});
dropzone.addEventListener("drop", (e) => {
e.preventDefault();
e.stopPropagation();
dropzone.classList.remove("dragover");
handleFiles(e.dataTransfer.files);
});
dropzone.addEventListener("dragenter", (e) => {
e.preventDefault();
e.stopPropagation();
dropzone.classList.add("dragover");
});
dropzone.addEventListener("click", () => {
input.click();
});
input.addEventListener('change', (event) => {
const files = event.target.files;
if (files.length > 0) {
const fileName = files[0].name;
document.querySelector('.filename').textContent = fileName;
upload.style.display = 'none';
}
});
dropzone.addEventListener('click', () => {
input.click();
})
uploadBtn.addEventListener('click', () => {
const files = document.querySelector('.input').files;
if (files.length > 0) {
dropzone.style.transition = 'opacity 0.5s ease';
syncing.style.transition = 'opacity 1s ease';
dropzone.style.opacity = '0';
syncing.style.opacity = '0.3';
line.classList.add('active');
uploadBtn.textContent = 'Uploading...';
setTimeout(() => {
done.style.transition = 'opacity 1s ease';
syncing.style.transition = 'opacity 0.5s ease';
syncing.style.opacity = '0';
done.style.opacity = '0.3';
uploadBtn.textContent = 'Done!';
input.value = '';
}, 5000);
}
});
this is what i tried to click everywhere in the dropzone :
dropzone.addEventListener("click", () => { input.click(); });