Drag & Drop
by webgleb
HTML
<div class="row">
<div class="placeholder">
<div class="col-header start">Начать</div>
<div class="item" draggable="true">Перетащи меня</div>
</div>
<div class="placeholder">
<div class="col-header progress">В процессе</div>
</div>
<div class="placeholder">
<div class="col-header done">Готовы</div>
</div>
</div>
CSS
@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');
* {
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
background-color: #e5e5e5;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
overflow: hidden;
width: 100%;
}
.row {
margin-bottom: 1rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 20px 20px;
}
.col-header {
width: calc(100% + 20px);
box-shadow: 4px 4px 9px rgba(198, 198, 198, 0.36);
color: #fff;
text-align: center;
padding: 15px 0;
margin: 0 -10px 15px -10px;
}
.item {
width: 100%;
box-sizing: border-box;
border: 1px solid #eee;
box-shadow: 4px 4px 9px rgba(198, 198, 198, 0.36);
border-radius: 10px;
background: #f7f6f7;
padding: 0.8rem 1rem;
margin: 0 10px;
color: #828282;
text-align: center;
cursor: grab;
}
.item:active {
cursor: grabbing;
}
.placeholder {
width: 270px;
height: 80vh;
min-height: 100px;
box-sizing: border-box;
border: 1px dashed #8a8a8a;
border-radius: 5px;
padding: 0 10px 10px 10px;
background: #fff;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.start {
background: linear-gradient(90deg, #ff85e4 0%, #229efd 179.25%);
}
.progress {
background: linear-gradient(90deg, #209cff 0%, #68e0cf 100%);
}
.done {
background: linear-gradient(90deg, #84fab0 0%, #8fd3f4 100%);
}
.hold {
border: 3px solid #eeeeee;
}
.hide {
display: none;
}
.hovered {
box-shadow: #9D9C9C 0 0 12px 6px;
}
JavaScript
const items = document.querySelectorAll('.item');
const placeholders = document.querySelectorAll('.placeholder');
let current = null
items.forEach((item) => {
item.addEventListener('dragstart', event => {
current = event.target
event.target.classList.add('hold')
setTimeout(() => {
event.target.classList.add('hide')
}, 0)
})
item.addEventListener('dragend', event => {
event.target.className = 'item';
current = null
})
})
placeholders.forEach((placeholder) => {
placeholder.addEventListener('dragover', event => {
event.preventDefault();
if (!event.target.classList.contains('placeholder')) return;
})
placeholder.addEventListener('dragenter', event => {
console.log('dragenter')
if (!event.target.classList.contains('placeholder')) return;
event.target.classList.add('hovered')
})
placeholder.addEventListener('dragleave', event => {
console.log('dragleave')
if (!event.target.classList.contains('placeholder')) return;
event.target.classList.remove('hovered')
})
placeholder.addEventListener('drop', event => {
console.log('dragdrop')
if (!event.target.classList.contains('placeholder')) return;
event.target.classList.remove('hovered')
event.target.append(current);
})
})