sorry, I don't know if this is an easy question or a difficult one and I'm just a newbie in JS, but I have a problem: I have a draggable element inside a div, it can be dragged freely. The thing is whenever I drag the element to the edges of the containing div the element's parts get hidden because of "overflow: hidden" (I purposely did that) but is there a way to make it like the edges of the element just bumps to the edges of the containing div instead of overflowing?
<div id="topDiv">
parent div
<div id="insideDiv">
<br> draggable content
<br>
</div>
</div>
html, body {
height: 100%;
margin: 0;
}
#topDiv {
background-color: lightblue;
max-height: 70%;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
}
#insideDiv {
background-color: pink;
overflow-y: auto;
}
var container = document.querySelector("#topDiv");
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target !== e.currentTarget) {
active = true;
activeItem = e.target; // this is the item we are interacting with
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("doing something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}
function setTranslate(xPos, yPos, el) {
currentPosX = xPos;
currentPosY = yPos;
el.style.transform = "translate(" + xPos + "px, " + yPos + "px)";
}
Here's my example: https://jsfiddle.net/ezmatto0911/r38he9no/13/
UPDATE: I've been able to get along with the getBoundingClientRect()
as mentioned by @N3R4ZZuRR0 but I still run into some problems:
here's my updated code:
html, body {
height: 100%;
margin: 0;
}
#topDiv {
background-color: lightblue;
max-height: 50%;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
}
#insideDiv {
background-color: pink;
width: 30%;
overflow-y: auto;
}
<div id="topDiv">
<div>
Parent Div
</div>
<div id="insideDiv">
<br> element
<br>
</div>
</div>
var container = document.getElementById('topDiv');
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target !== e.currentTarget) {
active = true;
activeItem = e.target; // this is the item we are interacting with
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("doing something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
var div = document.getElementById("topDiv");
var rect = div.getBoundingClientRect();
x = rect.left;
y = rect.top;
r = rect.right;
b = rect.bottom;
var elementToCheck = document.getElementById(activeItem.id);
var rect2 = elementToCheck.getBoundingClientRect();
x2 = rect2.left;
y2 = rect2.top;
r2 = rect2.right;
b2 = rect2.bottom;
console.log('x: ' + x + ', y: ' + y + ', r: ' + r + ', b: ' + b);
console.log('x2: ' + x2 + ', y2: ' + y2 + ', r2: ' + r2 + ', b2: ' + b2);
if (x2 > x && y2 > y && r2 < r && b2 < b) {
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}else if (x2 <= x || y2 <= y || r2 >= r || b2 >= b){
if (x2 <= x) {
console.log('LEFT BOUND');
activeItem.xOffset = x + 2;
}
if (y2 <= y) {
console.log('TOP BOUND');
activeItem.yOffset = y + 2;
}
if (r2 >= r) {
console.log('RIGHT BOUND');
activeItem.xOffset = r - 2;
}
if (b2 >= b) {
console.log('BOTTOM BOUND');
activeItem.yOffset = b - 2;
}
setTranslate(activeItem.xOffset, activeItem.yOffset, activeItem);
}
}
}
function setTranslate(xPos, yPos, el) {
currentPosX = xPos;
currentPosY = yPos;
el.style.transform = "translate(" + xPos + "px, " + yPos + "px)";
}
here's my fiddle of this sample: https://jsfiddle.net/ezmatto0911/jowb584a/1/
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.