简体   繁体   中英

How do I limit draggable area? it functions on top and left side, but not on the right side and bottom

So I tried to block the draggable contents from overflowing the body.

It works on top and on the left side.

I can't limit the right side and bottom.

            e.pageX -= e.offsetX;
            e.pageY -= e.offsetY;

            // left/right constraint
            if (e.pageX - dragoffset.x < 0) {
                offsetX = 0;
            } else if (e.pageX + dragoffset.x > document.body.clientWidth) {
                offsetX = document.body.clientWidth - e.target.clientWidth;
            } else {
                offsetX = e.pageX - dragoffset.x;
            }

            // top/bottom constraint

            if (e.pageY - dragoffset.y < 0) {
                offsetY = 0;
            } else if (e.pageY + dragoffset.y > document.body.clientHeight) {
                offsetY = document.body.clientHeight - e.target.clientHeight;
            } else {
                offsetY = e.pageY - dragoffset.y;
            }   

            el.style.top = offsetY + "px";
            el.style.left = offsetX + "px";
        }
    });
};

Also, my divs are getting glitchy while I drag them around. They only stop on the right side and bottom when the text inside them is selected.

There is drag&drop library with feature to restrict movements of draggables

https://github.com/dragee/dragee

By default it restrict movements of element inside container . It take into account size of element.

import { Draggable } from 'dragee'
new Draggable(element, { container: document.body })

In same time it's possible to use custom bound function

import { Draggable, BoundToRectangle, Rectangle } from 'dragee'
new Draggable(element, { 
    bound: BoundToRectangle.bounding(Rectangle.fromElement(document.body, document.body))
})

where BoundToElement describe restrictions that you need

class BoundToRectangle {
  constructor(rectangle) {
    this.rectangle = rectangle
  }

  bound(point, size) {
    const calcPoint = point.clone()
    const rectP2 = this.rectangle.getP3()

    if (this.rectangle.position.x > calcPoint.x) {
      (calcPoint.x = this.rectangle.position.x)
    }
    if (this.rectangle.position.y > calcPoint.y) {
      calcPoint.y = this.rectangle.position.y
    }
    if (rectP2.x < calcPoint.x + size.x) {
      calcPoint.x = rectP2.x - size.x
    }
    if (rectP2.y < calcPoint.y + size.y) {
      calcPoint.y = rectP2.y - size.y
    }

    return calcPoint
  }
}

Size of element you can calculate next way:

let width = parseInt(window.getComputedStyle(element)['width'])
let height = parseInt(window.getComputedStyle(element)['height'])

I can also suggest to use translate3d property for movements instead of positions left and top, because it is more efficient

I assume that since the draggable item is a dom element it will push the width and height of the body when moved right or down, this changes the body size, so using the body size might not be the right way. Maybe you can use window.width and window.height or so to restrict the area with values the draggable item cannot change. Hope this helps.

thank you, I'll try! I hope it works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM