DEV Community

roggc
roggc

Posted on

How to continuously drag an element in React with javascript

In this post, I will show you an implementation for moving around an element with the mouse with the aid of javascript. The implementation is simple.

Here it is:

import React from 'react'
import styled from 'styled-components'

export const Ball=
()=>
{
  let offsetX,offsetY
  const move=e=>
  {
    const el=e.target
    el.style.left = `${e.pageX-offsetX}px`
    el.style.top = `${e.pageY-offsetY}px`
  }
  const add=e=>
  {
    const el=e.target
    offsetX=e.clientX-el.getBoundingClientRect().left
    offsetY=e.clientY-el.getBoundingClientRect().top
    el.addEventListener('mousemove',move)
  }
  const remove=e=>{
    const el=e.target
    el.removeEventListener('mousemove',move)
  }
  const Wrapper=styled.div`
  width: 50px;
  height: 50px;
  border-radius: 29px;
  box-shadow: 0 0 6px;
  position: absolute;
  top: 40px;
  left: 227px;
  background-color: rgb(0,0,0,0.5);
  cursor:pointer;
  `
  return (
    <Wrapper onMouseDown={add} onMouseUp={remove}/>
  )
}
Enter fullscreen mode Exit fullscreen mode

Let's comment on what happens here.
We define three event handlers: move, add, and remove.
The first one, move, is for moving around the element. It uses offsetX and offsetY to calculate the position to move. offsetX is the distance from where the mouse is positioned to the border (left) of the element. offsetY is the same with the Y coordinate. These two values are calculated on the add event handler (or function).
In the add function what we do is to attach the move function to the on mousemove event (with the element itself as a listener). And also we calculate the offsetX and offsetY values to be used later in the move function as we already commented about it.
Finally, what we do in the remove function is simply removing the previous attached event handler, that is, the move function to the on mousemove event.
If we look to the style what it is being painted here is like a ball, with absolute positioning.
So when we do mouse down on the ball (element) we execute the add function, adding the move function the mousemove event. When we release the button or do mouse up, we are removing this event handler.
This works and it's quite a simple implementation. Thank you.
As per request here it is a CodePen (without React):

Top comments (8)

Collapse
 
arhman profile image
Abed Alrahman Sayes

Neat code bro :)
BUT if you move mouse fast then the mouse is out of wrapper element and the onmousemove and onmouseup event listeners is not valid any more!

To avoid that issue add those listeners on the window object.

Collapse
 
roggc profile image
roggc

thanks a lot for your comment. you are totally right.

Collapse
 
levisnkyyyy profile image
Levisnkyyyy

How can you make it work on touch devices?

Collapse
 
corncobb profile image
Cameron Cobb

I would recommend wrapping the add and remove functions with a useCallback with nothing in dependency array.

Collapse
 
jurikonradi profile image
Jurijs Konradi

Very short and elegant code!
But if I drag the mouse faster it lugs, ball 'froze' at the old position.

Collapse
 
georgewl profile image
George WL

this is pretty neat.
could you embed or link a codepen/codesandbox in here so we can get a nice live preview too though?

Collapse
 
roggc profile image
roggc

done

Collapse
 
lucasferreiralimax profile image
Lucas

This delay with moving? i don't understand how remove this delay