Skip to content

Instantly share code, notes, and snippets.

@Millardiang
Created June 3, 2022 14:41
Show Gist options
  • Save Millardiang/98fe9b7eb78ad6f3fd81d1e8ec78670a to your computer and use it in GitHub Desktop.
Save Millardiang/98fe9b7eb78ad6f3fd81d1e8ec78670a to your computer and use it in GitHub Desktop.
css grid drag and drop
<section id="list">
<div id='div1' class='divRec'><div class='inside'>item 1</div></div>
<div id='div2' class='divQuad'><div class='inside'>item 2</div></div>
<div id='div3' class='divRec'><div class='inside'>item 3</div></div>
<div id='div4' class='divCard'><div class='inside'>item 4</div></div>
<div id='div5' class='divRec'><div class='inside'>item 5</div></div>
<div id='div6' class='divQuad'><div class='inside'>item 6</div></div>
<div id='div7' class='divCard'><div class='inside'>item 7</div></div>
<div id='div8' class='divRec'><div class='inside'>item 8</div></div>
</section>
/* still in progress */
function sortable(section, onUpdate){
var dragEl, nextEl, newPos, dragGhost;
let oldPos = [...section.children].map(item => {
item.draggable = true
let pos = document.getElementById(item.id).getBoundingClientRect();
return pos;
});
function _onDragOver(e){
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
var target = e.target;
if( target && target !== dragEl && target.nodeName == 'DIV' ){
if(target.classList.contains('inside')) {
e.stopPropagation();
} else {
//getBoundinClientRect contains location-info about the element (relative to the viewport)
var targetPos = target.getBoundingClientRect();
//checking that dragEl is dragged over half the target y-axis or x-axis. (therefor the .5)
var next = (e.clientY - targetPos.top) / (targetPos.bottom - targetPos.top) > .5 || (e.clientX - targetPos.left) / (targetPos.right - targetPos.left) > .5;
section.insertBefore(dragEl, next && target.nextSibling || target);
/* console.log("oldPos:" + JSON.stringify(oldPos));
console.log("newPos:" + JSON.stringify(newPos)); */
/* console.log(newPos.top === oldPos.top ? 'They are the same' : 'Not the same'); */
console.log(oldPos);
}
}
}
function _onDragEnd(evt){
evt.preventDefault();
newPos = [...section.children].map(child => {
let pos = document.getElementById(child.id).getBoundingClientRect();
return pos;
});
console.log(newPos);
dragEl.classList.remove('ghost');
section.removeEventListener('dragover', _onDragOver, false);
section.removeEventListener('dragend', _onDragEnd, false);
nextEl !== dragEl.nextSibling ? onUpdate(dragEl) : false;
}
section.addEventListener('dragstart', function(e){
dragEl = e.target;
nextEl = dragEl.nextSibling;
/* dragGhost = dragEl.cloneNode(true);
dragGhost.classList.add('hidden-drag-ghost'); */
/* document.body.appendChild(dragGhost);
e.dataTransfer.setDragImage(dragGhost, 0, 0); */
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('Text', dragEl.textContent);
section.addEventListener('dragover', _onDragOver, false);
section.addEventListener('dragend', _onDragEnd, false);
setTimeout(function (){
dragEl.classList.add('ghost');
}, 0)
});
}
sortable( document.getElementById('list'), function (item){
/* console.log(item); */
});
/* The setData() method is used to add an item to the drag data, as shown in the following example.
function dragstart_handler(ev) {
// Add the drag data
ev.dataTransfer.setData("text/plain", ev.target.id);
ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>");
ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org"); */
/* you may succeed this a hacky solution. The native draggability doesn't allow CSS styles like: opacity:0;, visibility:hidden or display:none.
But you can do it using: transform:translateX(-9999px).
I've updated your JSFiddle with the solution. */
section {
margin: 0;
padding: 0;
list-style: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
display: grid;
grid-gap: 15px;
grid-template-rows: repeat(5, 200px);
grid-template-columns: repeat(5, 1fr);
/* grid-template-columns: repeat(auto-fit, minmax(300px, 300px));
grid-template-rows: repeat(5, 200px); */
grid-auto-flow: row dense;
min-height: 100vh;
}
.inside {
background-color: #fff;
}
.divRec {
cursor: move;
padding: 35px 20px;
font-size: 20px;
background-color: #ff0000;
grid-area: span 1/span 2;
}
.divQuad {
cursor: move;
padding: 35px 20px;
font-size: 20px;
background-color: #fff333;
grid-area: span 1/span 1;
}
.divCard {
cursor: move;
padding: 35px 20px;
font-size: 20px;
background-color: #00ff00;
grid-area: span 2/span 1;
}
.ghost {
border: 1px dashed #000;
background-color: #fff;
}
.custom-drag-ghost {
/* The original cloned element must not take place up in the page and must not be visible */
position: absolute;
top: -99999px;
left: -99999px;
/* Just for appearance */
background-color: #edb458;
border: 1px solid #e8871e;
}
.hidden-drag-ghost {
opacity: 0;
}
.transition {
transition: all 2s ease-out .5s;
top: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment