【问题标题】:How do I only allow an item to be dropped in a certain place in HTML/JavaScript?如何只允许将项目放置在 HTML/JavaScript 中的某个位置?
【发布时间】:2020-03-01 21:00:48
【问题描述】:

您好,StackOverflow 社区的同胞!在过去的几周里,我一直致力于 HTML/JavaScript 的拖放。基本上,我有一个圆圈和两个盒子。圆圈可以拖动到屏幕上的任何位置。但是,我需要它,所以圆圈只能放在两个盒子之一内。尽管进行了几天的研究,但我无法弄清楚如何做到这一点。提前谢谢!

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" 
        content="width=device-width, 
        initial-scale=1.0, 
        user-scalable=no" />
  <title>Drag/Drop/Bounce</title>
  <style>
    #item {
      width: 100px;
      height: 100px;
      background-color: rgb(245, 230, 99);
      border: 10px solid rgba(136, 136, 136, .5);
      border-radius: 50%;
      touch-action: none;
      user-select: none;
    }

    #box1 {
      width: 200px;
      height: 200px;
      background-color: red;
    }

    #box2 {
      width: 200px;
      height: 200px;
      background-color: lightblue;
    }
  </style>
</head>

<body>
<h1>Drag and Drop</h1>
<div id="box1">
  <div id="item"></div>
</div>
<br>
<div id="box2"></div>

  <script>
    var dragItem = document.querySelector("#item");
    var container = dragItem;

    //Declare Variables
    var active = false;
    var currentX;
    var currentY;
    var initialX;
    var initialY;
    var xOffset = 0;
    var yOffset = 0;

    //Add Event Listeners for Touchscreens
    container.addEventListener("touchstart", dragStart, false);
    container.addEventListener("touchend", dragEnd, false);
    container.addEventListener("touchmove", drag, false);

    //Add Event Listeners for Mice
    container.addEventListener("mousedown", dragStart, false);
    container.addEventListener("mouseup", dragEnd, false);
    container.addEventListener("mousemove", drag, false);

    function dragStart(e) { //when the drag starts
      if (e.type === "touchstart") { //if its a touchscreen
        initialX = e.touches[0].clientX - xOffset; //set initial x-cordinate to where it was before drag started
        initialY = e.touches[0].clientY - yOffset; //set initial y-cordinate to where it was before drag started
      } else { //if its not a touchscreen (mouse)
        initialX = e.clientX - xOffset; //set initial x-cordinate to where it was before drag started
        initialY = e.clientY - yOffset; //set initial y-cordinate to where it was before drag started
      }

      if (e.target === dragItem) { //if user is dragging circle
        active = true; //the drag is active
      }
    }

    function dragEnd(e) { //when the drag ends
      initialX = currentX; //set the initial x-cordinate to where it is now
      initialY = currentY; //set the initial y-cordinate to where it is now

      active = false; //the drag is no longer active
    }

    function drag(e) { //when the circle is being dragged
      if (active) { //if the drag is active
        e.preventDefault(); //the user cant do anything else but drag

        if (e.type === "touchmove") { //if its a touchscreen
          currentX = e.touches[0].clientX - initialX; //set current x-cordinate to where it is now
          currentY = e.touches[0].clientY - initialY; //set current y-cordinate to where it is now
        } else { //if its not a touchscreen (mouse)
          currentX = e.clientX - initialX; //set current x-cordinate to where it is now
          currentY = e.clientY - initialY; //set current y-cordinate to where it is now
        }

        //Im not sure what this does but it dosnt work without it
        xOffset = currentX;
        yOffset = currentY;
        setTranslate(currentX, currentY, dragItem);
      }
    }

    function setTranslate(xPos, yPos, el) { //Im not sure what this does but it dosnt work without it
      el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
    }
  </script>
</body>

</html>

我还为喜欢的人上传了代码到 TryIt:https://www.w3schools.com/code/tryit.asp?filename=GCF4V2RIT7T4

【问题讨论】:

  • 你读过the documentation吗?这很简单。似乎您想阅读标题为“定义放置区”的部分。此外,请始终在您的问题中发布您的代码,而不是在第 3 方位置,因为这些链接可能会随着时间的推移而失效,从而使您的问题对于遇到它的人来说毫无意义。
  • 此外,众所周知,W3 Schools 的信息不完整、过时或只是简单的不正确信息。从来源获取您的信息,即Mozilla Developers Network
  • W3Schools 过去的文章中有很多不准确的信息,但它们大多已经成型。不幸的是,他们仍然受到像你这样有一段时间没有上 W3S 并且不知道他们改变了的人的坏名声。无论如何都没有关系,因为我没有链接到 W3Schools 文章。我链接到他们的代码共享平台 TryIt,它有我自己的代码。如果单击该链接,您将看到它是用户制作的代码。那个用户就是我。这是我的代码,不是 W3Schools 的代码。
  • 此外,Marcus 先生,您链接的文档似乎正在讨论丢弃事件,例如 one of my previous questions 中的那些。我在这里使用触摸事件和鼠标事件。我不相信我正在使用任何丢弃事件。

标签: javascript html css drag-and-drop


【解决方案1】:

在此版本中,您只能在红色框内移动圆圈。我认为您可以采用它并轻松实现另一个框。

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" 
    content="width=device-width, 
    initial-scale=1.0, 
    user-scalable=no" />
  <title>Drag/Drop/Bounce</title>
  <style>
#item {
  width: 100px;
  height: 100px;
  background-color: rgb(245, 230, 99);
  border: 10px solid rgba(136, 136, 136, .5);
  border-radius: 50%;
  touch-action: none;
  user-select: none;
  position: absolute;
}

#box1 {
  width: 200px;
  height: 200px;
  background-color: red;
}

#box2 {
  width: 200px;
  height: 200px;
  background-color: lightblue;
}
  </style>
</head>

<body>
<h1>Drag and Drop</h1>
<div id="item"></div>
<div id="box1">
</div>
<br>
<div id="box2"></div>

  <script>
var dragItem = document.querySelector("#item");
var box1 = document.querySelector("#box1");
var box2 = document.querySelector("#box2");
var container = dragItem;
//Declare Variables
var active = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;

//Add Event Listeners for Touchscreens
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);

//Add Event Listeners for Mice
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);

function dragStart(e) { //when the drag starts
  if (e.type === "touchstart") { //if its a touchscreen
    initialX = e.touches[0].clientX - xOffset; //set initial x-cordinate to where it was before drag started
    initialY = e.touches[0].clientY - yOffset; //set initial y-cordinate to where it was before drag started
  } else { //if its not a touchscreen (mouse)
    initialX = e.clientX - xOffset; //set initial x-cordinate to where it was before drag started
    initialY = e.clientY - yOffset; //set initial y-cordinate to where it was before drag started
  }
  if (e.target === dragItem) { //if user is dragging circle
    active = true; //the drag is active
  }
}

function dragEnd(e) { //when the drag ends
  const box1Size = box1.getBoundingClientRect()
  const elementSize = dragItem.getBoundingClientRect()
  if (elementSize.left >= box1Size.left && elementSize.right <= box1Size.right && elementSize.top >= box1Size.top && elementSize.bottom <= box1Size.bottom) {
    initialX = currentX; //set the initial x-cordinate to where it is now
    initialY = currentY; //set the initial y-cordinate to where it is now
  } else {
   	currentX = 0
    currentY = 0
	initialX = 0
    initialY = 0
    xOffset = 0;
    yOffset = 0;
  	setTranslate(0, 0, dragItem);
  }
  
  active = false; //the drag is no longer active
}

function drag(e) { //when the circle is being dragged
  if (active) { //if the drag is active
    e.preventDefault(); //the user cant do anything else but drag
  
    if (e.type === "touchmove") { //if its a touchscreen
      currentX = e.touches[0].clientX - initialX; //set current x-cordinate to where it is now
      currentY = e.touches[0].clientY - initialY; //set current y-cordinate to where it is now
    } else { //if its not a touchscreen (mouse)
      currentX = e.clientX - initialX; //set current x-cordinate to where it is now
      currentY = e.clientY - initialY; //set current y-cordinate to where it is now
    }
    
    //Im not sure what this does but it dosnt work without it
    xOffset = currentX;
    yOffset = currentY;
    setTranslate(currentX, currentY, dragItem);
  }
}

function setTranslate(xPos, yPos, el) { //Im not sure what this does but it dosnt work without it
  el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
  </script>
</body>

</html>

【讨论】:

  • 这几乎是完美的!我可以处理另一个盒子,但你知道如何制作它,如果它没有放在盒子里,圆圈会回到原来的位置,而不是回到红色盒子的左上角。我试过 setTranslate(initialX, initialY, dragItem);但这似乎不起作用。谢谢!
猜你喜欢
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多