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>
© 20072025 XoaX.net LLC. All rights reserved.