This JavaScript program shows how to drag and drop with multiple styles on an element using classes and click locations. The example also includes an element that serves as a drag image.
<!DOCTYPE html>
<html>
<head>
<style>
div {
border:1px gray solid;
width:250px;
height:50px;
}
.cB1 {
background-color: lightblue;
}
.cB2 {
background-color: gray;
}
.cB3 {
background-color: red;
}
.cB1.cB2 {
background: linear-gradient(90deg, lightblue, lightblue 50%, gray 50%, gray);
}
.cB1.cB3 {
background: linear-gradient(90deg, lightblue, lightblue 50%, red 50%, red);
}
.cB2.cB3 {
background: linear-gradient(90deg, gray, gray 50%, red 50%, red);
}
.cB1.cB2.cB3 {
background: linear-gradient(90deg, lightblue 0%, lightblue 33%, gray 33%, gray 66%, red 66%, red 100%);
}
</style>
<script>
// Store the dragged element during the drag
var gqDragSrcElement = null;
function allowDrop(qEvent) {
qEvent.preventDefault();
}
function onDragStart(qEvent) {
// Store the drag source element
gqDragSrcElement = qEvent.target;
// Get the style count.
let iClassCount = gqDragSrcElement.classList.length;
// Get the x coordinate of the drag within the current element
let iLocalDragStartX = qEvent.offsetX;
let iElementWidth = gqDragSrcElement.clientWidth;
let dClassWidth = iElementWidth/iClassCount;
let iSelectedClassIndex = Math.floor(iLocalDragStartX/dClassWidth);
let sClass = gqDragSrcElement.classList[iSelectedClassIndex];
// Get the coordinates of the click, using the offset
qEvent.dataTransfer.setData("text", sClass);
// The drag image element must be a visible element on the page, it seems.
let qDragImage = document.getElementById("idDragImage");
qDragImage.className = sClass;
qEvent.dataTransfer.setDragImage(qDragImage, qEvent.offsetX, qEvent.offsetY);
}
function onDrop(qEvent) {
qEvent.preventDefault();
var sClass = qEvent.dataTransfer.getData("text");
var qSrcElement = gqDragSrcElement;
var qTargetElement = qEvent.target;
// Prevent change for self-drops
if (qSrcElement === qTargetElement) {
return;
}
MakeDraggable(qTargetElement, sClass);
RemoveDraggability(qSrcElement, sClass);
}
function MakeDraggable(qElement, sClass) {
// Add the class and resort the class list to ensure that they are in order for the selection
qElement.classList.add(sClass);
SortClasses(qElement.classList);
qElement.draggable = true;
//qElement.className = sClass;
qElement.addEventListener("dragstart", onDragStart);
}
function RemoveDraggability(qElement, sClass) {
// Remove the class and resort the class list to ensure that they are in order for the selection
qElement.classList.remove(sClass);
SortClasses(qElement.classList);
// If all classes are gone, make it undraggable.
if (qElement.classList.length == 0) {
qElement.draggable = false;
qElement.removeEventListener("dragstart", onDragStart);
}
}
// A simple sort does not seem to work because the list is read only, but this does
function SortClasses(qaClassList) {
const kiClassCount = qaClassList.length;
// An ordered list of all of the classes.
// Run through this to make sure that classes are added in order.
let saClasses = ["cB1", "cB2", "cB3"];
let saOrderedClasses = new Array();
for (let i = 0; i < saClasses.length; ++i) {
// If the next class is in the list add it the order array
if (qaClassList.contains(saClasses[i])) {
saOrderedClasses.push(saClasses[i]);
qaClassList.remove(saClasses[i]);
}
}
// Add the order classes back
for (let i = 0; i < saOrderedClasses.length; ++i) {
qaClassList.add(saOrderedClasses[i]);
}
}
</script>
</head>
<body>
<!-- The second line of properties get altered on drop -->
<div ondrop="onDrop(event)" ondragover="allowDrop(event)"
draggable="true" class="cB1 cB2 cB3" ondragstart="onDragStart(event)">
</div>
<div ondrop="onDrop(event)" ondragover="allowDrop(event)"></div>
<p>The element below serves as a drag image.</p>
<div id="idDragImage"></div>
</body>
</html>© 20072026 XoaX.net LLC. All rights reserved.