Create a Draggable Element in JavaScript

You can just store the transform X and Y values on each element to get the same result. I don’t recommend using the the top and left properties for performance reasons.

Thank you for your response, now it is much easier to drag :slight_smile: But now I have a new problem - I can’t get the file to scale. The settings I had before I placed the url(filehere) in css, was that the element should be 60% of the windows width, but not bigger than 363px (width: 60%;, max-width: 363px;). That worked when I had the img src in html, but not now when I need the image file to be in css. I tried to place the img src in between the div in html, but then my original problem occurs (you have to click once more to let the item go). I tried making a container around the div as well, but it still doesn’t work. Now it looks like this:

#containerElement1 {
position: relative;
max-width: 363px;
max-height: 139px;
width: 60%;
height: auto;
}

#element1 {
background-image: url(illustrasjon/nase1.png);
display: block;
width: 100%;
height: auto;
}

Correction, this is how it looks like in the css file:

#containerElement1 {

position: relative;

max-width: 363px;

max-height: 139px;

width: 60%;

height: auto;

}

#element1 {

background-image: url(illustrasjon/nase1.png);

display: block;

width: 263px;

height: 139px;

}

Do you have the example hosted anywhere that we can take a look at? :slight_smile:

Here is the webpage: http://folk.ntnu.no/manordt/wu1/Heimeside/framside.html

The code is a bit messy now because I have been trying out different things :slight_smile: But the first element is the one I can’t get to scale properly (id=“element1”). The other elements on the page is how it looks when the file is in the html document.
Then it doesn’t drag properly.

That helps greatly! The issue is that the drag code doesn’t like any child elements like our image to be placed inside the div. The trick is to disable mouse/touch events on the image. Here is an example: https://www.kirupa.com/html5/examples/drag_multiple_images.htm

The main change is the following style rule that I added:

.item img {
  pointer-events: none;
}

You may need to modify your style rule to be .element img, but that will fix it for you as well. I set it on all images via your existing img style rule, and it worked.

Cheers,
Kirupa

Thank you so much! It worked :smiley: Buuuut… Every time something works, it affects something else :joy: Now all my elements get to small, I figured out it is because the javascript I have that randomly places the objects inside the browser window. Maybe it doesn’t like that I use element img in css, and then only refers to element in the script? Do you have any idea how I can fix this? I should send you a medal soon for helping me so much out :sweat_smile:
Webpage: folk.ntnu.no/manordt/wu1/Heimeside/framside.html

Haha. Welcome to web development :stuck_out_tongue:

The reason for the sizes doesn’t seem to have anything to do with the JavaScript or how you are placing them on the page. All of your images are respecting the size you have specified:

.element img {
    max-width: 363px;
    width: 60%;
    pointer-events: none;
}

If you increase the width and max-width values, you’ll find that your images grow to match your new size. Try that and let us know if that solves it for you.

Cheers,
Kirupa

Figured it out, thank you! Again! I figured out it was because I was using the .element img {} to scale it within the browser window, but I guess it then scaled within the div instead? So I moved the max-width and width: 60% to .element {}, and in .element img {width: 100%;}. Now it works! I also added some code that prevent the images from being highlighted when dragged. Now it looks like this in the CSS file:
.element {
max-width: 363px;
width: 60%;
user-select: none;
-ms-user-select: none;
-moz-user-select: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
}

.element img {
pointer-events: none;
width: 100%;
}

.element:active {
opacity: .75;
}

.element:hover {
cursor: pointer;
}

Thanks again, you’re a real life saver! Now my webpage is finally ready to be launched :smiley:

1 Like

That is awesome! Glad to hear you are unblocked :slight_smile:

Hi there, I’m trying your code and for some reason it doesn’t get past the condition for the if statement in dragStart.

if(e.target === detailPanel) {
active = true;
}

detailPanel being my dragItem.

I’m trying to drag an element (toggled on the draggable in the html attributes) which has a few things inside. It’s basically a card, or as the name implies, a detail panel with lots of info in it.

If I console log out my detailPanel variable it does select the right element so I’m not sure why the script can’t get into the if statement.

var detailPanel = document.getElementsByClassName('detailTabWrappper');
console.log(detailPanel);
var panelContainer = document.body;
console.log(panelContainer);
var active = false;

var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;

panelContainer.addEventListener('mousedown', dragStart);
panelContainer.addEventListener('mouseup', dragEnd);
panelContainer.addEventListener('mousemove', drag);

function dragStart(e) {
  if(e.type === 'mousedown') {
    initialX = e.clientX - xOffset;
    initialY = e.clientY - yOffset;
  }

  // this here is not working
  if(e.target === detailPanel) {
    active = true;
  }
}

<article class="detailTabWrappper" draggable="true"></article>

Any ideas why?

One thing is that getElementsByClassName returns an array. Try this:

var detailPanel = document.getElementsByClassName('detailTabWrappper')[0];

That will ensure detailPanel points to an element instead of the array. Does that fix it?

Cheers,
Kirupa :stuck_out_tongue:

It works.

I can’t believe I got owned by that a second time. That the getEByClass returns an array.

Thanks!

1 Like

Thanks Kirupa for your post on drag and drop in javascript. It really helped me to learn about multiple drag and drop elements.

1 Like

Thanks for the comment! Glad the tutorial helped :slight_smile:

I’m trying to create a drag and select around multiple countries in a svg of the world.
The box should resize and grab user selected countries. tia, David
http://datamaps.github.io/

HELP
It runs, not clean, and needs fixes.
Can someone suggest how to fix the reset to (0,0) bug on reload+dragStart.
(https://codepen.io/Danny1897/pen/LaYBxK)

How do I write a sortable component, based on an items position property?

I am creating a Tangram game for children’s therapy sessions. I need to drag shapes on the page and rotate them in 22.5 deg increments to make the tangram images. I have the drag code (from your tutorial) done but have been unable to rotate the shapes to fit patterns that will be loaded by the user onto the page. Tangram so far can be seen at www.hansondesignmaine.com. Thank you for any help you can provide. Jack

Correction to web page name it is: www.hansondesignmaine.com/tangram/tangram.html Thanks, Jack