skip to Main Content

I’ve got a script that lets you drag around a box called "draggable-container." There are also a couple of other things on the screen: a "window" and a footer. I’m wondering how I can make sure that when you’re dragging the "draggable-container," you can’t drag it over the "window" or the footer.

For example, if you start dragging the box and then try to move it over the "window" or the footer, I want it to just stop moving. How can I make this happen?

My code:

// appDrag.js

const draggableContainer = document.getElementById("draggable-container");
let isDragging = false;
let xOffset, yOffset;

draggableContainer.addEventListener("mousedown", (event) => {
  isDragging = true;
  xOffset = event.clientX - draggableContainer.getBoundingClientRect().left;
  yOffset = event.clientY - draggableContainer.getBoundingClientRect().top;

  // Add the "dragging" class to the entire container when dragging starts
  draggableContainer.classList.add("dragging");
});

document.addEventListener("mousemove", (event) => {
  if (isDragging) {
    event.preventDefault();
    draggableContainer.style.left = event.clientX - xOffset + "px";
    draggableContainer.style.top = event.clientY - yOffset + "px";
  }
});

document.addEventListener("mouseup", () => {
  isDragging = false;

  // Remove the "dragging" class when dragging ends
  draggableContainer.classList.remove("dragging");
});

I have tried implementing boundary checks, etc, but they either just don’t work, or just stop draggable-container from working.

2

Answers


  1. To prevent draggableContainer from moving over another square element, you can check to make sure that the two elements would not overlap before moving them.

    document.addEventListener("mousemove", (event) => {
      if (isDragging) {
        const obstacle = /* an element you don't want to overlap with */;
    
        // The position of the top left corner of the draggable box
        const goalX = event.clientX - xOffset + "px";
        const goalY = event.clientY - yOffset + "px";
    
        // The size of the draggable box
        const draggableWidth = draggableContainer.getBoundingClientRect().width;
        const draggableHeight = draggableContainer.getBoundingClientRect().height;
    
        // The position of the top left corner of the obstacle
        const obstacleX = obstacle.getBoundingClientRect().top;
        const obstacleY = obstacle.getBoundingClientRect().left;
    
        // The size of the obstacle
        const obstacleWidth = obstacle.getBoundingClientRect().width;
        const obstacleHeight = obstacle.getBoundingClientRect().height;
    
        // If the two elements overlap
        // See https://stackoverflow.com/questions/12066870
        const rectsOverlap = !(goalX + draggableWidth < obstacleX || 
          goalX > obstacleX + obstacleWidth || 
          goalY + draggableHeight < obstacleY || 
          goalY > obstacleY + obstacleHeight);
    
        // If the obstacle and the place where the draggable box would be
        // if it is successfully moved overlap, don't move the box.
        if (!rectsOverlap) {
          event.preventDefault();
          draggableContainer.style.left = event.clientX - xOffset + "px";
          draggableContainer.style.top = event.clientY - yOffset + "px";
        }
      }
    });
    
    Login or Signup to reply.
  2. It sounds like you want to restrict the movement of the "draggable-container" so that it cannot be dragged over the "window" or the footer elements. To achieve this, you can add boundary checks in your code to prevent the container from being dragged outside the desired areas.

    Here’s how you can modify your existing code to achieve this:

    // appDrag.js
    
    const draggableContainer = document.getElementById("draggable-container");
    const windowElement = document.getElementById("window"); // Replace with your window element's ID
    const footerElement = document.getElementById("footer"); // Replace with your footer element's ID
    
    let isDragging = false;
    let xOffset, yOffset;
    
    draggableContainer.addEventListener("mousedown", (event) => {
      isDragging = true;
      xOffset = event.clientX - draggableContainer.getBoundingClientRect().left;
      yOffset = event.clientY - draggableContainer.getBoundingClientRect().top;
    
      // Add the "dragging" class to the entire container when dragging starts
      draggableContainer.classList.add("dragging");
    });
    
    document.addEventListener("mousemove", (event) => {
      if (isDragging) {
        event.preventDefault();
    
        // Calculate the new position
        const newX = event.clientX - xOffset;
        const newY = event.clientY - yOffset;
    
        // Get the boundaries of the window and footer
        const windowRect = windowElement.getBoundingClientRect();
        const footerRect = footerElement.getBoundingClientRect();
    
        // Check if the new position is within the boundaries
        if (
          newX >= windowRect.left &&
          newX + draggableContainer.offsetWidth <= windowRect.right &&
          newY >= windowRect.top &&
          newY + draggableContainer.offsetHeight <= footerRect.top
        ) {
          // Update the position only if it's within the boundaries
          draggableContainer.style.left = newX + "px";
          draggableContainer.style.top = newY + "px";
        }
      }
    });
    
    document.addEventListener("mouseup", () => {
      isDragging = false;
    
      // Remove the "dragging" class when dragging ends
      draggableContainer.classList.remove("dragging");
    });
    

    In this code, the position of the "draggable-container" is only updated if the new position is within the boundaries defined by the "window" and the area above the "footer". This prevents the container from being dragged over these elements. Make sure to replace "window" and "footer" with the actual IDs of your window and footer elements.

    Remember that this solution assumes that the "window" and footer elements are not dynamically resized or moved, as the boundary checks are based on the initial positions of these elements. It could be further changed, but for the basic solution, it is enough.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search