# Create a Draggable Element in JavaScript

**URL:** <https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149>\
**Category:** programming\
**Created:** [April 28, 2018, 5:27am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149 "2018-04-28T05:27:37Z")\
**Posts on this page:** 20\
**Page:** 6

<div class="post-metadata">

**Author:** ![Three\_X](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/three_x/32/11504_2.png) [@Three\_X](https://forum.kirupa.com/u/Three_X)\
**Post date:** [April 19, 2020, 1:05pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/105 "2020-04-19T13:05:18Z")

</div>

Hi, Kirupa @kirupa

Thanks for the great tutorial.  
Please help me I only want to make a draggable player div miniplayer  
when change the class with jquary

Example: [https://codepen.io/xvids/pen/KKdMrOq](https://codepen.io/xvids/pen/KKdMrOq)

Thanks…

---

<div class="post-metadata">

**Author:** ![n2fole00](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/n2fole00/32/11561_2.png) [@n2fole00](https://forum.kirupa.com/u/n2fole00)\
**Post date:** [April 27, 2020, 6:39am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/106 "2020-04-27T06:39:52Z")

</div>

Hi, I expanded on this example to include mouse scrolling. However, I have to move the mouse after the scroll action, in order for the element position to be rendered. Is there a way to update and render the position on scroll alone?  
Here is an example fiddle of what I have. Thanks.  
[https://jsfiddle.net/n2fole00/Lxdjf15h/](https://jsfiddle.net/n2fole00/Lxdjf15h/)

---

<div class="post-metadata">

**Author:** ![icuccia](https://avatars.discourse-cdn.com/v4/letter/i/3ec8ea/32.png) [@icuccia](https://forum.kirupa.com/u/icuccia)\
**Post date:** [June 11, 2020, 4:53pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/107 "2020-06-11T16:53:46Z")

</div>

Hi @kirupa  
This tutorial helped me a lot and is so well explained!  
Thank you for sharing it!

I noticed that the draggable element goes outside its container on mobile. How can I prevent this behaviour? I would like it to move only inside the container and stop just before the edges of the container (as it already happens on desktop).

Thanks in advance

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 12, 2020, 4:06am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/108 "2020-06-12T04:06:58Z")

</div>

Hi @icuccia! Welcome to the forums 🙂

Even on desktop, the draggable element goes outside the container. At least when I tested, holding a circle at the edge and dragging it towards an opposing side:

 ![image](https://canada1.discourse-cdn.com/flex011/uploads/kirupa/original/2X/2/273a88faaea461e555086c345e4d19beada1ebbc.png)

Do you still want to stop the circle from hitting the edge, or are you interested in having consistent behavior between mobile and desktop?

Cheers,  
Kirupa

---

<div class="post-metadata">

**Author:** ![icuccia](https://avatars.discourse-cdn.com/v4/letter/i/3ec8ea/32.png) [@icuccia](https://forum.kirupa.com/u/icuccia)\
**Post date:** [June 12, 2020, 8:07am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/109 "2020-06-12T08:07:42Z")

</div>

Hi @kirupa  
Thanks for your quick response!

I would like to stop the circle to go outside the container on both desktop and mobile.  
Is there a way to do so?

Thanks

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 13, 2020, 3:58pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/110 "2020-06-13T15:58:45Z")

</div>

Yes - there is a way to do that, but I have been too busy with work this week to fiddle with this 😛

One approach that would work is having a boolean value for moving up, down, left, and right and stopping movement in a particular direction if the edge of a circle hits an appropriate edge. I was thinking IntersectionObserver could help with that.

The other approach is that we know the size of the circle and the size of the container. We can mathematically calculate the boundary and restrict movement that way.

I don’t know how helpful this is, but these are the things running through my mind on how I would potentially implement this.

Cheers,  
Kirupa 🤓

---

<div class="post-metadata">

**Author:** ![draco](https://avatars.discourse-cdn.com/v4/letter/d/b4bc9f/32.png) [@draco](https://forum.kirupa.com/u/draco)\
**Post date:** [June 15, 2020, 9:19am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/111 "2020-06-15T09:19:37Z")

</div>

Hi Kirupa! Thanks a lot for your tutorial!  
In a program I’m working on, I’d like to cancel the drag and drop effect once a button has been clicked on, meaning that you cannot drag or drop once that button has been pressed. I was thinking of maybe using element.onclick and cancel all the eventListeners for dragging and dropping, how can I achieve that?

Thanks again for sharing!

---

<div class="post-metadata">

**Author:** ![Tony\_Zhang](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/tony_zhang/32/11923_2.png) [@Tony\_Zhang](https://forum.kirupa.com/u/Tony_Zhang)\
**Post date:** [June 20, 2020, 10:36pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/112 "2020-06-20T22:36:04Z")

</div>

Is it bad for the mousemove eventlistener to be called every time that the mouse moves even when it’s not dragging anything? I know there is an if statement but doesn’t the function still have to check the if statement every time it is moved? can you add eventlistener when it’s needed and remove it on mouse up?

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 21, 2020, 6:20am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/113 "2020-06-21T06:20:35Z")

</div>

That is a great observation. I did some benchmarking on this a short while ago, and the differences aren’t that noticeable for this particular case since the calculations performed for a drag aren’t computationally intensive. One optimization that I have done in other implementations of this is to use `requestAnimationFrame` to throttle chatty events like our mousemove.

[![](https://canada1.discourse-cdn.com/flex011/uploads/kirupa/original/2X/8/82df9e5ae0dc11c9a112bf5365389d00a11a6841.jpeg "Throttling Chatty Events in JavaScript") ](https://www.youtube.com/watch?v=iL2PzejeLmg)

The techniques outlined there may help 🙂

Cheers,  
Kirupa

---

<div class="post-metadata">

**Author:** ![vancoder](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vancoder/32/11930_2.png) [@vancoder](https://forum.kirupa.com/u/vancoder)\
**Post date:** [June 21, 2020, 4:56pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/114 "2020-06-21T16:56:24Z")

</div>

Hi I am new here but have been learning various aspects of JS for a few years. I loved this tutorial and made my own working example. My question is how do I create a radial boundry? I created a square one easy enough as you can see, but that makes the element drag a bit choppy on the corners.  
Here is the src (forgive me if It does not fornat right. I am new to posting code)

> #boundry { width: 25vh; height: 25vh; background: grey; border-radius: 100%; position: absolute; bottom: 0vh; } #pad{ width: 15vh; height: 15vh; background: lightgrey; border-radius: 100%; position: relative; } 
> Active
> 
> Initial X Value
> 
> Initial Y Value
> 
> Current X Value
> 
> Current Y Value
> 
> X Offset
> 
> Y Offset
> 
> ```
> <script type="text/javascript" charset="utf-8">
> (function app(){
> //ui for controller
> const boundry = document.getElementById("boundry");
> const pad = document.getElementById("pad");
> //ui for data
> const startingX = document.getElementById("initialX"); 
> const startingY = document.getElementById("initialY");
> const activeX = document.getElementById("currentX");
> const activeY = document.getElementById("currentY");
> const offSetX = document.getElementById("xOffset");
> const offSetY = document.getElementById("yOffset");
>   
> //init variables
> let activeState = false; 
> let currentX,
> currentY,
> initialX,
> initialY,
> xOffset = 0,
> yOffset = 0,
> bOffsetWidth = boundry.offsetWidth,
> bOffsetHeight = boundry.offsetHeight;
> padOffsetWidth = pad.offsetWidth;
> padOffsetHeight = pad.offsetHeight;
> const log = console.log;
>   
>   
> //Create event listeners
> pad.addEventListener("touchstart", dragStart, false); 
> pad.addEventListener("touchend", dragEnd, false); 
> pad.addEventListener("touchmove", drag, false); 
> pad.addEventListener("mousedown", dragStart, false); 
> pad.addEventListener("mouseup", dragEnd, false); 
> pad.addEventListener("mousemove", drag, false); 
>   
> //function triggers on touchstart or mousedown
> function dragStart(e) { 
> if (e.type === "touchstart") { 
> initialX = e.touches[0].clientX - xOffset; 
> initialY = e.touches[0].clientY - yOffset;
> //ui code
> startingX.value = initialX;
> startingY.value = initialY;
> offSetX.value = xOffset;
> offSetY.value = yOffset;
>       
> } else { 
> initialX = e.clientX - xOffset; 
> initialY = e.clientY - yOffset;
> } 
> if (e.target === pad) { 
> activeState = true; 
> //ui code
> isActive.value = activeState;
> } 
> } 
>   
> //function triggers on touchend or mouseup
> function dragEnd(e) { 
> initialX = currentX; 
> initialY = currentY; 
> activeState = false;
> //ui code
> isActive.value = activeState;
> } 
>   
> //function triggers on touchmove or mousemove
> function drag(e) { 
> if (activeState) { 
> e.preventDefault(); 
> if (e.type === "touchmove") { 
> currentX = e.touches[0].clientX - initialX; 
> currentY = e.touches[0].clientY - initialY; 
>         
> //boundry code
> if(currentX > bOffsetWidth - padOffsetWidth){
> currentX = bOffsetWidth - padOffsetWidth;
> } else if(currentX < 0) {
> currentX = 0;
> }
> if(currentY > bOffsetHeight - padOffsetHeight){
> currentY = bOffsetHeight - padOffsetHeight;
> } else if(currentY < 0){
> currentY = 0;
> }
>         
> //ui code
> activeX.value = currentX;
> activeY.value = currentY;
>         
> } else { 
> currentX = e.clientX - initialX; 
> currentY = e.clientY - initialY;
> } 
> xOffset = currentX; 
> yOffset = currentY;
>       
> setTranslate(currentX, currentY, pad); 
> } 
> } 
>   
> function setTranslate(xPos, yPos, el) { 
> el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)"; 
> }
> })();
> </script>
> 
> ```

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 22, 2020, 6:22am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/115 "2020-06-22T06:22:14Z")

</div>

I don’t have a non-d3 solution, but this may help you: [javascript - Limit drag movements to a circular SVG boundary - Stack Overflow](https://stackoverflow.com/questions/25620544/limit-drag-movements-to-a-circular-svg-boundary)

A SVG boundary might be the easiest way to do this, but I haven’t tried it to know what gotchas you may run into ☹

---

<div class="post-metadata">

**Author:** ![vancoder](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vancoder/32/11930_2.png) [@vancoder](https://forum.kirupa.com/u/vancoder)\
**Post date:** [June 22, 2020, 1:34pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/116 "2020-06-22T13:34:28Z")

</div>

Thank you Kirupa. Ill play around with it. I did some research and found that you can mathimatically define an imaginary circle inaide a square. If I get it working Ill post an update.

---

<div class="post-metadata">

**Author:** ![BradleyMeck](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/bradleymeck/32/11960_2.png) [@BradleyMeck](https://forum.kirupa.com/u/BradleyMeck)\
**Post date:** [June 26, 2020, 2:39pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/117 "2020-06-26T14:39:26Z")

</div>

A nice addition to this program would be too include [element.setPointerCapture](https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture) so that dragging outside of the window still gets touch events.

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 26, 2020, 3:38pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/118 "2020-06-26T15:38:53Z")

</div>

Good idea! I will add it to my notes when updating this article shortly 😀

---

<div class="post-metadata">

**Author:** ![topcrickets](https://avatars.discourse-cdn.com/v4/letter/t/e19b73/32.png) [@topcrickets](https://forum.kirupa.com/u/topcrickets)\
**Post date:** [June 30, 2020, 1:09pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/119 "2020-06-30T13:09:06Z")

</div>

Thanks, these are helpful for me

---

<div class="post-metadata">

**Author:** ![marcospdsf](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/marcospdsf/32/12275_2.png) [@marcospdsf](https://forum.kirupa.com/u/marcospdsf)\
**Post date:** [August 20, 2020, 1:44pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/120 "2020-08-20T13:44:23Z")

</div>

Hi, I am using your code and trying to add items via document.createElement, and it works really well, except the fact that when I create the element it keeps going to the left, infinitively, wich is like when I create a element it creates its div, and as I move the element (or not) the div is still created that place so the “display:flex” will keep trying to add next to the div, and the thing keeps growing and hiding the other elements… Anyone got any ideas?

---

<div class="post-metadata">

**Author:** ![vancoder](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vancoder/32/11930_2.png) [@vancoder](https://forum.kirupa.com/u/vancoder)\
**Post date:** [August 20, 2020, 3:14pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/121 "2020-08-20T15:14:09Z")

</div>

Try centering the flex box of divs. Look up the CSS for coding the layout of the actual flex box.  
You may also want to center the actual div as well as it’s content.

---

<div class="post-metadata">

**Author:** ![marcospdsf](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/marcospdsf/32/12275_2.png) [@marcospdsf](https://forum.kirupa.com/u/marcospdsf)\
**Post date:** [August 23, 2020, 11:25am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/122 "2020-08-23T11:25:34Z")

</div>

So aparently, setting the Item as absolute works fine… Wich is weird since last time I tried it went everywhere…

---

<div class="post-metadata">

**Author:** ![Apostolos\_POLYMEROS](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/apostolos_polymeros/32/12730_2.png) [@Apostolos\_POLYMEROS](https://forum.kirupa.com/u/Apostolos_POLYMEROS)\
**Post date:** [October 28, 2020, 8:38am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/123 "2020-10-28T08:38:42Z")

</div>

Dear all,

I am trying to add some boundary on this code but I fail. Let’ s say something like the element cannot be dragged over 200px upwards. Any idea someone. Thank all the community a lot

---

<div class="post-metadata">

**Author:** ![Philippe\_Lagarrigue](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/philippe_lagarrigue/32/12927_2.png) [@Philippe\_Lagarrigue](https://forum.kirupa.com/u/Philippe_Lagarrigue)\
**Post date:** [November 23, 2020, 9:12am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/125 "2020-11-23T09:12:17Z")

</div>

Hi Kirupa, thank you for this excellent description!  
I am creating a game with letters and I would like that when I move a letter, it should snap to a position relative to a grid. Could you please tell me how can I correct the end position in the dragEnd () function, I have tried using el.style.top and el.style.left but it does not give satisfactory results.

[Previous page](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149.md?page=5)

[Next page](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149.md?page=7)
