2

I'm trying to make a draggable div, but I run into confusing behavior. The solution is copied from w3schools and it works correctly for them, but not for me. With a slight movement of the mouse, div always moves to the left, even if the mouse is moved up or down, and only with a large movement to the right, div follow the cursor.

div.js

constructor(props){
    super(props)
    this.state = {
        x: this.props.x,
        y: this.props.y,
    }
    this.dragMouseDown = this.dragMouseDown.bind(this)
    this.elementDrag = this.elementDrag.bind(this)
    this.closeDragElement = this.closeDragElement.bind(this)
    this.reff = React.createRef()
}

componentDidMount(){
    this.pos1 = 0
    this.pos2 = 0
    this.pos3 = 0
    this.pos4 = 0
}

dragMouseDown(e) {
    e.preventDefault()
    this.pos3 = e.clientX
    this.pos4 = e.clientY
    document.onmouseup = this.closeDragElement
    document.onmousemove = this.elementDrag
}

elementDrag(e) {
    e.preventDefault()
    this.pos1 = this.pos3 - e.clientX
    this.pos2 = this.pos4 - e.clientY
    this.pos3 = e.clientX
    this.pos4 = e.clientY
    this.setState({
        y:(this.reff.current.offsetTop - this.pos2) + "px",
        x:(this.reff.current.offsetLeft - this.pos1) + "px",
    })
}

closeDragElement() {
    document.onmouseup = null
    document.onmousemove = null
}

render(){
    return (
        <div className="tech row align-items-center justify-content-center border rounded"
             style={{left: this.state.x, top: this.state.y}}
             onMouseDown={this.dragMouseDown}
             ref={this.reff}
        >
                <img className="technology-icon" src={image} alt="technology_logo"></img>
                <span className="ml-1">{this.props.name}</span>
        </div>
    )
}

Css with this div and container for it

.t_d{
    position: relative;
    width: 80%;
    height: 100%;
    overflow: hidden;
    overflow-x: auto;
    overflow-y: auto;
    border: 1px solid black;
}
 .tech{
    width: 150px;
    height: 50px;
    border-radius: 6px;
    position: absolute;
 }

And html for this (rows - an array of div components)

<div id="app"  style="height: 100%">
  <div className="fluid-container" style={{height: "100%"}}>
    <nav className="navbar navbar-dark bg-dark" id="nav">
        <a className="navbar-brand" href="#">Navbar</a>
    </nav>
    <div className="t_d">
            {rows}
    </div>
</div>
</div>

Also, I tried to do something like the code below, and it works, but I don’t like the fact that the div is shifted to the cursor

this.setState({
        y: e.clientY - this.height + this.td.scrollTop + "px",
        x: e.clientX + this.td.scrollLeft + "px"
    })
2
  • I also saw this example on react. My problem was for a little drag the div goes out of screen scope (due to huge displacement) Commented Jul 5, 2019 at 16:43
  • Does this answer your question? Implementing a basic drag functionality in ReactJS Commented Oct 11, 2021 at 10:07

1 Answer 1

1

The problem was in the "row" class in "tech" div. Removed it and everything began to work as it should. Ha-ha.

<div className="tech border rounded"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.