Core JavaScript

Drag and Drop Multiple Styles

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.

DragAndDropMultipleStyles.html

<!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>
 

Output

 
 

© 2007–2025 XoaX.net LLC. All rights reserved.