可拖动的div并单击到元素后面

时间:2019-06-27 21:37:30

标签: javascript jquery html css

我到底想要什么?

  

使可移动div后面的元素可点击。

这是我尝试过的,但无法正常工作。而且我没有为此找到任何其他解决方案。这将对我有很大的帮助。

  

添加样式“指针事件:无;”但是应用这种风格之后   div不可拖动。

这是我的代码:

红色Div可以移动,但是不可点击,绿色Div可以单击,但是不可移动

function make_movable(id) {

  var movable_div = document.getElementById(id);
  movable_div.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;
    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:
    movable_div.style.top = (movable_div.offsetTop - pos2) + "px";
    movable_div.style.left = (movable_div.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    document.onmouseup = null;
    document.onmousemove = null;
  }

}

make_movable("movable_div1");
make_movable("movable_div2");
#movable_div1 {
  cursor: move;
  background: green;
  width: 100px;
  height: 100px;
  position: absolute;
  pointer-events: none;
  opacity: 0.5;
}

#movable_div2 {
  cursor: move;
  background: red;
  width: 100px;
  height: 100px;
  position: absolute;
  opacity: 0.5;
  /*pointer-events: none;*/
}

button {
  width: 100px;
  padding: 10px;
  margin: 10px;
}
<button onClick="alert('Just pressed button 1');">BUTTON 1</button>
<button onClick="alert('Just pressed button 2');">BUTTON 2</button>
<button onClick="alert('Just pressed button 3');">BUTTON 3</button>
<button onClick="alert('Just pressed button 4');">BUTTON 4</button>
<button onClick="alert('Just pressed button 5');">BUTTON 5</button>
<button onClick="alert('Just pressed button 6');">BUTTON 6</button>
<button onClick="alert('Just pressed button 7');">BUTTON 7</button>
<button onClick="alert('Just pressed button 8');">BUTTON 8</button>
<button onClick="alert('Just pressed button 9');">BUTTON 9</button>
<button onClick="alert('Just pressed button 10');">BUTTON 10</button>

<div id="movable_div1" style="top: 40px; left: 40px;"> </div>
<div id="movable_div2" style="top: 160px; left: 40px;"> </div>

2 个答案:

答案 0 :(得分:1)

这是可能的,但是有点混乱

您可以检查用户是否在www.bah.com-和mousedown事件之间移动了鼠标。如果鼠标没有移动,则假定用户单击了鼠标。现在,我们只需要暂时隐藏可移动元素,并使用它来查找当前鼠标位置最上方的元素。然后,我们创建一个新的mouseup事件(单击),并将其分派到基础元素,然后再次显示可移动元素。

示例:

MouseEvent
function make_movable(id) {
  var movable_div = document.getElementById(id);
  movable_div.onmousedown = dragMouseDown;
  let didDrag = false; // did the user perform a drag (mousemove)

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

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    didDrag = true;
    // 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:
    movable_div.style.top = (movable_div.offsetTop - pos2) + "px";
    movable_div.style.left = (movable_div.offsetLeft - pos1) + "px";
  }

  function closeDragElement(e) {
    e = e || window.event;
    if (!didDrag) {
      // copy display-property of moveable-element
      let displayCopy = movable_div.style.display;
      // hide moveable-element
      movable_div.style.display = 'none';
      // get x- and y-position from current event
      let x = e.clientX,
          y = e.clientY;
      // create click event with position
      let event = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true,
        clientX: x,
        clientY: y
      });
      // get underlying-element at mouse-position
      let element = document.elementFromPoint(x, y);
      // restore display-property of moveable-element
      movable_div.style.display = displayCopy;
      // dispatch event for the underlying-element
      element.dispatchEvent(event);
    }
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

make_movable("movable_div1");
make_movable("movable_div2");
make_movable("movable_div3");
#movable_div1 {
  cursor: move;
  background: green;
  width: 100px;
  height: 100px;
  position: absolute;
  pointer-events: none;
  opacity: 0.5;
}

#movable_div2 {
  cursor: move;
  background: red;
  width: 100px;
  height: 100px;
  position: absolute;
  opacity: 0.5;
  /*pointer-events: none;*/
}

#movable_div3 {
  cursor: move;
  background: purple;
  width: 100px;
  height: 100px;
  position: absolute;
  opacity: 0.5;
}

button {
  width: 100px;
  padding: 10px;
  margin: 10px;
}

经过Firefox 67(macOS)的测试。

答案 1 :(得分:1)

您可以使用setTimeout来检查用户是否在单击或拖动。

timer = setTimeout(() => {
  document.onmousemove = elementDrag;
  isDragging = true;
}, 400);

如果onmousedown事件的触发时间超过400毫秒,而onmouseup事件尚未触发,我们可以假定用户正在尝试拖动元素。而且,如果onmouseup事件在400毫秒内触发,我们可以假定用户正在尝试单击元素或它后面的按钮。

function tryClick(e) {
  var { clientX, clientY } = e;
  var element = document.elementFromPoint(clientX, clientY);
  if (element.classList.contains("clickable")) {
    element.hidden = true;
    tryClick(e);
    element.hidden = false;
  } else if (element.tagName == "BUTTON") {
    element.click();
  }
}

tryClick函数是一个递归函数,用于检查鼠标当前指向的元素是否为clickable。如果是,则将其隐藏并检查其后面的元素,依此类推。如果不是,请检查元素是否为BUTTON并触发click

function make_movable(id) {

  var movable_div = document.getElementById(id);
  movable_div.onmousedown = dragMouseDown;

  var timer = null,
      isDragging = false;

  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;

    // check if the element is movable
    if (!movable_div.classList.contains("movable")) return;

    timer = setTimeout(() => {
      document.onmousemove = elementDrag;
      isDragging = true;
    }, 400);
  }


  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:
    movable_div.style.top = (movable_div.offsetTop - pos2) + "px";
    movable_div.style.left = (movable_div.offsetLeft - pos1) + "px";
  }

  function closeDragElement(e) {
    clearTimeout(timer);
    timer = null;
    if (!isDragging) {
      tryClick(e);
    } else {
      isDragging = false;
    }
    document.onmouseup = null;
    document.onmousemove = null;
  }

  function tryClick(e) {
    var { clientX, clientY } = e;
    var element = document.elementFromPoint(clientX, clientY);
    if (element.classList.contains("clickable")) {
      element.hidden = true;
      tryClick(e);
      element.hidden = false;
    } else if (element.tagName == "BUTTON") {
      element.click();
    }
  }
}

make_movable("movable_div1");
make_movable("movable_div2");
make_movable("movable_div3");
#movable_div1 {
  cursor: move;
  background: green;
  width: 100px;
  height: 100px;
  position: absolute;
  pointer-events: none;
  opacity: 0.5;
}

#movable_div2 {
  cursor: move;
  background: red;
  width: 100px;
  height: 100px;
  position: absolute;
  opacity: 0.5;
  /*pointer-events: none;*/
}

#movable_div3 {
  cursor: move;
  background: lightblue;
  width: 100px;
  height: 100px;
  position: absolute;
  opacity: 0.5;
  /*pointer-events: none;*/
}

button {
  width: 100px;
  padding: 10px;
  margin: 10px;
}
<button onClick="alert('Just pressed button 1');">BUTTON 1</button>
<button onClick="alert('Just pressed button 2');">BUTTON 2</button>
<button onClick="alert('Just pressed button 3');">BUTTON 3</button>
<button onClick="alert('Just pressed button 4');">BUTTON 4</button>
<button onClick="alert('Just pressed button 5');">BUTTON 5</button>
<button onClick="alert('Just pressed button 6');">BUTTON 6</button>
<button onClick="alert('Just pressed button 7');">BUTTON 7</button>
<button onClick="alert('Just pressed button 8');">BUTTON 8</button>
<button onClick="alert('Just pressed button 9');">BUTTON 9</button>
<button onClick="alert('Just pressed button 10');">BUTTON 10</button>

<div id="movable_div1" class="clickable" style="top: 40px; left: 40px;"> </div>
<div id="movable_div2" class="movable" style="top: 160px; left: 40px;"> </div>
<div id="movable_div3" class="movable clickable" style="top: 40px; left: 160px;"> </div>