Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

JavaScript How to STOP Drag-n-Drop Finicky behavior ?

vmars316

Well-Known Coder
Hello & Thanks :

Working-Example here :
https://vmars.us/Guitar/Guitar-Scales-and-Boxes-Builder-1-Note-4-Frets-FORUM.html

The working-example is VERY finicky ,
in that when Dragging an item ,
the Cursor keeps loosing the item , as you can view at link above ,
Forcing me to keep going back and Grabbing Target again & again .
Else I have to Drag at a sloth's pace .
Source-Code :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guitar-Scales-and-Boxes-Builder-1-Note-4-Frets-FORUM.html</title>
<!-- https://www.freeformatter.com/html-validator.html -->
<style>
body {
margin: 20px;
background-color: #FFFFFF;
}
.flex-container {
display: flex;
}

.flex-container > div {
font-size: 20px;
}
#container {
width: 100%;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
counter-reset: itemCount;
}
.item {
display: inline-block;
border-radius: 50%;
touch-action: none;
user-select: none;
counter-increment: itemCount;
content: 'count' + itemCount;
width: 32px;
height: 32px;
background-color: #F5F5F5; // whitesmoke
font-family: Arial, Helvetica, sans-serif;
text-align:center;
font-size:28px;
z-index: 8;
}

.flatOne , sharpOne , naturalOne { background-color: #DCDCDC;
z-index: 5;
}

#itemContainer { }
#tableContainer { }
#fretboardContainer { background-color: #DCDCDC;
}
tbody { background-color:#636363;
}
#tbodyId { background-color:#636363;
}
.item:active {
opacity: .75;
}
.item:hover {
cursor: pointer;
}
</style>
</head>

<body>
<div id="outerContainer"> <!-- BEGIN OF id="outerContainer -->

<p>
X: <span id="x"></span><br>
Y: <span id="y"></span>
</p>

<!-- BEGIN of id="itemContainer" -->
<div id="itemContainer" class="flex-container POS" style="position: absolute; top: 40px; display: flex; ">
<div class="item flatOne" style=" z-index:5; position: absolute; left: 100px; top: 0; background-color: #DCDCDC" > b</div>
<div class="item one" style=" position: absolute; left: 400px; top: 0; background-color: #FF0004;" > 1</div>
<div class="item sharpOne" style=" z-index:5; position: absolute; left: 700px; top: 0; background-color: #DCDCDC;" > ♯</div>
<div class="item naturalOne" style=" z-index:5; position: absolute; left: 1000px; top: 0; background-color: #DCDCDC;" > ♮</div>
</div> <!-- END of id="itemContainer" -->

<div id="tableContainer" style=" position: absolute; top: 155px; left: 55px; "> <!-- BEGIN of id="tableContainer" -->
<table id="fretboardContainer" style=" position: absolute ; width: 1200px;"> <!-- BEGIN of id="fretContainer" -->
<!-- Start Copy Here -->
<tbody id="tbodyId" style="background-color:#636363;">
<tr style="height: 40px; border-bottom: 2px solid red; border-top: 3px solid white;">
<!-- Row 1 -->
<td style="vertical-align: top; border-bottom: 3px solid white; border-top: 4px solid white;"><br>
</td>
<td style="vertical-align: top; border-bottom: 2px solid white; border-top: 4px solid white;"><br>
</td>
<td style="vertical-align: top; border-bottom: 2px solid white; border-top: 4px solid white;"><br>
</td>
<td style="vertical-align: top; border-bottom: 2px solid white; border-top: 4px solid white;"><br>
</td>
</tr>
</tbody>
</table> <!-- END OF fretContainer -->
</div> <!-- END OF tableContainer -->
</div> <!-- END OF id="outerContainer -->

<div style='text-align: center; position:absolute; bottom: 40px;'>Drag and Drop</div>

<!-- BEGIN SCRIPT ZZZZZZZZZZZZZZZZZ -->
<script>
window.addEventListener('mousemove', (event) => {
let x = event.clientX;
let y = event.clientY;

document.getElementById('x').innerHTML = x;
document.getElementById('y').innerHTML = y;
});
</script>

<script>
var container = document.querySelector("#itemContainer");
var activeItem = null;

var active = false;

container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);

container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);

function dragStart(e) {

if (e.target !== e.currentTarget) {
active = true;

// this is the item we are interacting with
activeItem = e.target;

if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}

if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}

if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("Dragging something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}

function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}

active = false;
activeItem = null;
}

function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();

activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}

activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;

setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}

function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
</script>

</body>
</html>

The code above is a chuncked-down version of this :
You may ask "Why not use id="" instead instead of class="" ?
If you view the html source , you will see that every .item has 6-duplicates ;
which turns out to be 7 x 7 = 49 .items .
So if I use id= I'll have to code 49 unique id='s .
Also , I will soon need to increase # .items to 7 x 14 = 98 .items .

So my question is how can I avoid this finicky-behavior , still using class="" ?

Thanks for your Help...
 
Can you please post code in BBCode tags ?

I don't understand what you are doing here.... We just got drag and drop to work, and the first thing you do is write your own implementation with mouse events ? Why ?

I am actually not surprised it behaves like it does. When you drag too fast the cursor moves out of the element (because the repainting can't keep up) and the process breaks.

Are you going this way because of the expected need for 98 unique id's ? Note that you do not have to hardcode these in your HTML. You can programmatically assign these in a loop in your page load handler. Just give all these thingies a special class name, and loop through them using getElementsByClassName, setting an incremental id for each element.
 
Can you please post code in BBCode tags ?
Oops , Sorry , Actually what I was doing , is putting link into Editor , Selecting it , Then clicking on BBCode .
Guess I need to Click on BBCode first .

I don't understand what you are doing here.... We just got drag and drop to work, and the first thing you do is write your own implementation with mouse events ? Why ?
I am actually not surprised it behaves like it does. When you drag too fast the cursor moves out of the element (because the repainting can't keep up) and the process breaks.

The whole reason I am Posting , is to Debug WHY the process breaks. .
IN : https://vmars.us/Guitar/W3schools-Drag-and-Drop-and-Back-RedDot-Only.html the Process does NOT break . WHY ?

Are you going this way because of the expected need for 98 unique id's ? Note that you do not have to hardcode these in your HTML. You can programmatically assign these in a loop in your page load handler. Just give all these thingies a special class name, and loop through them using getElementsByClassName, setting an incremental id for each element.

Yes , that sounds do-able .
But upon thinking it through again and again , considering the problems so far ;
I am thinking
I can make all the current Circles non-dragable , and just Clickable ,
and CLONE a new Circle as needed , with a unique id="" (similar to what you suggest above) .
That would decrease HTML coding and cut down on file size .

You wouldn't happen have an example in your back pocket , of .js Cloning an Element , would you ? 🙂
 
The whole reason I am Posting , is to Debug WHY the process breaks.
Always good to want to understand why something breaks. I just question your reasoning for doing it like that in the first place.
I told you why (I think) the process breaks. Did that not make sense to you ?

Because that code uses the built-in drag-and-drop functionality, which probably is a whole lot smarter and more intricate than we think. I guess it may use thread locking or some other mechanism to avoid the mouse pointer and element blithely drifting apart like in your (home-rolled?) code.

I can make all the current Circles non-dragable , and just Clickable ,
If it is always a specific place they need to move to, as I think it is, I'd certainly do that. Not having to drag saves energy 😀

You wouldn't happen have an example in your back pocket , of .js Cloning an Element , would you ? 🙂
Nope. But cloneNode() is your friend !.
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom