Hallo,
ich habe hier eine Liste mit zwei droppable-Boxen, bei denen die Items von einer zur anderen Box geschoben werden koennen. Nun moechte ich das aber nur über eine Handle-Fläche verschiebbar machen.
Was muss ich ändern, damit das Ziehen nur mit einen bestimmten Bereich (Griff) möglich ist (der Rest z. B. auswählbarer Text)?
Code
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
vertical-align: top;
background: #AAA;
}
.droppable {
border: 1px solid #EEE;
border-radius: 0.5rem;
overflow: auto;
}
.droppable:first-child {
width: 40%;
}
.draggable:before{
position:relative;
pointer-events:auto;
top:-40px;
left:-20px;
width:20px;
height:40px;
background:red;
display:block;
content:'';
}
.droppable:nth-child(2) {
width: 40%;
max-width: 700px;
overflow: auto;
}
h3 {
color: #FFF;
font-weight: normal;
font-size: 1.2rem;
}
div.btns {
display: flex;
justify-content: flex-end;
align-items: flex-end;
align-content: space-around;
gap: 10px;
padding: 0px 30px;
}
.shadow {
box-shadow: 6px 8px 6px -6px black;
}
.btn1 {
cursor: pointer;
border-radius: 0.5rem;
}
a:link {
color: #333;
text-decoration: none;
}
div.cat {
color: #FFF;
width: 100%;
height: 30px;
display: flex;
justify-content: space-around;
font-style: italic;
}
.draggable {
margin: 1rem 1rem;
min-width: 10rem;
max-width: 10rem;
min-height: 9rem;
pointer-events:none;
cursor: move;
display: inline-block;
padding: 5px;
text-align: center;
font-size: 1rem;
color: #e9550c;
background-color: rgba(240, 240, 240, 0.7);
border: 1px solid #CCC;
border-radius: 0.5rem;
transition: var(--transitionTime);
}
.dragging {
opacity: 0.5;
}
div {
display: inline-block;
vertical-align: top;
}
.new-added {
animation: insert var(--transitionTime) linear;
}
.will-remove {
animation: remove var(--transitionTime) linear;
animation-fill-mode: forwards;
}
@keyframes insert {
from {
max-height: 0;
}
to {
max-height: 10vh;
}
}
@keyframes remove {
from {
max-height: 100vh;
}
to {
max-height: 0;
opacity: 0;
}
}
.handle {
background: #FEF;
width: 100%;
border: 1px solid #333;
}
</style>
</head>
<body>
<div class="dTime" style="display: flex; justify-content: flex-end; gap: 10px; margin-right: 20px;"></div>
<div class="cat">
<span>Box 1 </span>
<span>Box 2 </span></div>
<div style="width: 100%">
<div class="droppable">
<div class="draggable" draggable="true">
<div class="handle">handle1</div><br />
<div class="content">content1 </div>
</div>
<div class="draggable" draggable="true">
<div class="handle">handle2</div><br />
<div class="content">content2 </div>
</div>
<div class="draggable" draggable="true">
<div class="handle">handle3</div><br />
<div class="content">content3 </div>
</div>
</div>
<div class="droppable">
<div class="draggable" draggable="true">
<div class="handle">handle4</div><br />
<div class="content">content4 </div>
</div>
<div class="draggable" draggable="true">
<div class="handle">handle5</div><br />
<div class="content">content5 </div>
</div>
<div class="draggable" draggable="true">
<div class="handle">handle6</div><br />
<div class="content">content6 </div>
</div><!--
<div class="draggable" draggable="true">
<div class="handle">handle7</div><br />
<div class="content">content7 </div>
</div>-->
</div>
</div>
<script>
const droppables = document.querySelectorAll('.droppable');
const draggables = document.querySelectorAll('.draggable');
const transitionTime = 500;
let dragging;
let cloned;
document.body.style.setProperty('--transitionTime', transitionTime + 'ms');
function cleanClass(className) {
const elements = document.querySelectorAll(`.${className}`);
for (const el of elements) {
el.classList.remove(className);
}
}
function delCookie() {
setCookie('cBrowser','','Fri, 02 Jan 1970 00:00:00 UTC');
setCookie('cCode','','Fri, 02 Jan 1970 00:00:00 UTC');
setCookie('cZeit','','Fri, 02 Jan 1970 00:00:00 UTC');
setCookie('cHost','','Fri, 02 Jan 1970 00:00:00 UTC');
setCookie('cVers','','Fri, 02 Jan 1970 00:00:00 UTC');
window.location.href='./srv/inc/logout.php';
}
// drag start
document.addEventListener('dragstart', e => {
if (e.target.classList.contains('draggable')) {
dragging = e.target;
dragging.classList.add('dragging');
cloned = dragging.cloneNode(true);
}
});
//document.addEventListener(eventName, function (e) {
// // loop parent nodes from the target to the delegation node
// for (var target = e.target; target && target != this; target = target.parentNode) {
// if (target.matches(elementSelector)) {
// handler.call(target, e);
// break;
// }
// }
//}, false);
function handleDragEnd() {
if (!dragging) return;
dragging.classList.add('will-remove');
setTimeout(() => {
dragging.remove();
cleanClass('dragging');
}, [transitionTime]);
}
// drag end
document.addEventListener('dragend', e => {
cleanClass('dragging');
cleanClass('new-added');
});
// drag over
droppables.forEach(droppable => {
droppable.addEventListener('dragover', e => {
e.preventDefault();
// In the column to be moved to, the closest element in front of dragging
const frontSib = getClosestFrontSibling(droppable, e.clientY);
// dragging the previous element currently in the DOM tree
const previousSib = dragging.previousElementSibling;
if (frontSib) {
if (
frontSib.nextElementSibling === cloned ||
frontSib === cloned ||
frontSib === previousSib
) {
return;
}
cloned.classList.add('new-added');
frontSib.insertAdjacentElement('afterend', cloned);
handleDragEnd(dragging);
} else {
if (
droppable.firstChild === cloned ||
droppable.firstChild === dragging
) {
return;
}
if (dragging.parentNode === droppable && !previousSib) {
return;
}
// set on the first position
cloned.classList.add('new-added');
droppable.prepend(cloned);
handleDragEnd(dragging);
}
});
});
// Get the nearest neighbor before the moved element
function getClosestFrontSibling(droppable, draggingY) {
const siblings = droppable.querySelectorAll('.draggable:not(.dragging)');
let result;
for (const sibling of siblings) {
const box = sibling.getBoundingClientRect();
// Get the center Y of the sibling
const boxCenterY = box.y + box.height / 2;
if (draggingY >= boxCenterY) {
result = sibling;
} else {
// draggingY < boxCenterY Description: Either the nearest adjacent element in front has been found, or it has been dragged to the first position
return result;
}
}
return result;
}
</script>
</bo0dy>
</html>