getBoundingClientRect returns 一如既往地触摸

getBoundingClientRect returns as always touching

试图让它检测每个元素何时被可拖动元素触摸,但它 returns 因为 reaction2 总是触摸,即使元素远离 reaction2

js:

dragElement(document.getElementById("draggable"));

function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.id + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
    
    touches(physical, reaction, "physical")
    touches(chemical, reaction, "chemical")
  }

  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

//draggable code^
let reacTouch;
let reacType;
var physical = document.getElementById("physical")
var chemical = document.getElementById("chemical")
var reaction = document.getElementById("draggableheader")

function touches(el1, el2, reacTouch) {
  const r1 = el1.getBoundingClientRect();
  const r2 = el2.getBoundingClientRect();
  
  if (r2.left - r1.right < 1) {
    console.log('touching');
  }
  else {
    console.log('not touching');
  }
}

html:

<span id='physical' class="phys">physical change</span>
<span id='chemical' class="chem">chemical change</span>


<div id="draggable">
  <div id="draggableheader"></div>
</div>

CSS:

#draggable {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}

#draggableheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}

.phys {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  float: 1;
  width: 50%;
  height: 100px;
  margin-top:20px;
  //position: absolute;
}

.chem {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  float: 1;
  width: 50%;
  height: 100px;
  margin-top:20px;
  position: relative;
  left: 300px;
}

无论如何都会将化学检测为接触,并在物理接触和不接触时正确检测

编辑:在代码示例中添加了更多详细信息以查看是否有其他问题,我只是误诊了问题

问题是检查两个元素是否接触的方法不够check:ing。它需要检查一个元素是否完全位于另一个元素的左侧,并以相反的方式重复检查。它还需要检查一个元素是否完全低于另一个元素,反之亦然。

几个小点:

  • //用于注释掉一行CSS,需要使用/*和 */配对。
  • 跨度被赋予了尺寸,但它们没有占用这些尺寸 - 也许您需要使它们成为内联 div。 (这不会改变 关于相对位置测试的要点)。

这是测试 left/right 和 top/bottom 位置的片段。请注意,他们测试重叠,而不是元素是否完全接触但不重叠 - 这对用户来说可能是一个相当困难的操作。

dragElement(document.getElementById("draggable"));

function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.id + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
    
    touches(physical, reaction, "physical")
    touches(chemical, reaction, "chemical")
  }

  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

//draggable code^
let reacTouch;
let reacType;
var physical = document.getElementById("physical")
var chemical = document.getElementById("chemical")
var reaction = document.getElementById("draggableheader")

function touches(el1, el2, reacTouch) {
  const r1 = el1.getBoundingClientRect();
  const r2 = el2.getBoundingClientRect();
  // to see whether 2 rectangles are overlapping or not check if one is totally to the left or totally above the other and vice-versa
  function dontOverlapLR(a, b) {return (a.right < b.left || (b.right < a.left)); }
  function dontOverlapTopBottom(a, b) {return (a.bottom < b.top || (b.bottom < a.top)); }
  if (dontOverlapLR(r1, r2) || dontOverlapTopBottom(r1, r2)) {
 // if (r2.left - r1.right < 1) {
    console.log('not touching' + reacTouch);//ADDED reacTouch
  }
  else {
    console.log('touching' + reacTouch);//ADDED reacTouch
  }
}
body {
  width: 100vw;
  height: 100vh;
}
#draggable {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}

#draggableheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}

.phys {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
 /* float: 1; */
  width: 50%;/* giving a span a width doesn't */
  height: 100px;
  margin-top:20px;
 /* //position: absolute;*/
}

.chem {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
/*  float: 1; */
  width: 50%;
  height: 100px;
  margin-top:20px;
  position: relative;
  left: 300px;
}
<span id='physical' class="phys">physical change</span>
<span id='chemical' class="chem">chemical change</span>


<div id="draggable">
  <div id="draggableheader"></div>
</div>