如何防止可拖动元素移动到边界之外? [英] How to keep a draggable element from being moved outside a boundary?

查看:31
本文介绍了如何防止可拖动元素移动到边界之外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过使用与w3Schools中的示例大致相同的代码来制作了可拖动元素:

I've made a draggable element by using code that works in more or less the same way as this example from w3Schools:

//Make the DIV element draggagle:
dragElement(document.getElementById(("mydiv")));

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;
    // 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;
    // 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";
  }

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

问题是我需要将元素限制在视口内,并需要少量填充.我有一个解决方案,您可以检查元素位置是否小于0,是否将其设置回0,或者是否大于width/height,将其设置为width/height.但这还不够好,因为它会产生一种我不想要的不稳定反弹效果.

The problem is I need the element to be restricted to inside the viewport plus a small bit of padding. I've got somewhat of a solution where you just check if the elements position is less than 0 and if it is set it back to 0 or if it's greater than the width/height set it to the width/height. This isn't good enough though as it creates a kind of janky bounce effect which I don't want.

所以我想知道是否存在针对此问题的更明显的解决方案?也不使用jQuery.

So I'm wondering if there's a more obvious solution to this problem? Without using jQuery as well.

推荐答案

您需要跟踪可用的视口(调整窗口大小可能会改变它),并确保该元素不会越过边界.如果该元素将越过边界,则除了使它越过然后再将其放回原处,您应该什么都不做.下面是一个有效的示例.

You need to keep track of the available viewport (a window resize may change it) and make sure the element won't cross the boundary. If the element will cross the boundary, you should do nothing rather than letting it cross and then setting it back. Below is a working example.

请注意,w3schools的代码示例在样式和功能用法上已经过时了-有更优雅的方法来支持现代HTML中的拖动.

Note well that the code example from w3schools is very outdated in its style and feature usage - there are more elegant ways to support dragging in modern HTML.

var PADDING = 8;

var rect;
var viewport = {
  bottom: 0,
  left: 0,
  right: 0,
  top: 0
}

//Make the DIV element draggagle:
dragElement(document.getElementById(("mydiv")));

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;
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    
    // store the current viewport and element dimensions when a drag starts
    rect = elmnt.getBoundingClientRect();
    viewport.bottom = window.innerHeight - PADDING;
    viewport.left = PADDING;
    viewport.right = window.innerWidth - PADDING;
    viewport.top = PADDING;
    
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    
    // check to make sure the element will be within our viewport boundary
    var newLeft = elmnt.offsetLeft - pos1;
    var newTop = elmnt.offsetTop - pos2;

    if (newLeft < viewport.left
        || newTop < viewport.top
        || newLeft + rect.width > viewport.right
        || newTop + rect.height > viewport.bottom
    ) {
    	// the element will hit the boundary, do nothing...
    } else {
      // set the element's new position:
      elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
      elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
    }
  }

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

#mydiv {
  border: 1px solid black;
  height: 100px;
  left: 8px;
  position: absolute;
  top: 8px;
  width: 100px;
}

<div id="mydiv"></div>

这篇关于如何防止可拖动元素移动到边界之外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆