在 JavaScript 中相对定位的元素上实现拖放

2022-01-11 00:00:00 drag-and-drop javascript

对于发布这么多问题,我深表歉意 - 我还在学习!所以,我可以在 html 中拖放第一个元素没有问题;但是,当我尝试拖放第二个时,它会出现在鼠标下方相当多.它仍然在我移动鼠标的任何地方拖动,但远低于.怎么了?

I apologize for posting so many questions- I'm still learning! So, I can drag and drop the first element in the html no problem; however, when I try to drag and drop the second one, it appears quite a bit below the mouse. It still drags wherever I move the mouse, but far below. What's wrong?

这里是javascript:

Here is the javascript:

// JavaScript Document

var posX;
var posY;
var element;

document.addEventListener("mousedown", drag, false);

function drag(event) {
    if(event.target.className == "square") {
        element = event.target;
        posX = event.clientX -parseInt(element.offsetLeft);
        posY = event.clientY -parseInt(element.offsetTop);
        document.addEventListener("mousemove", move, false);
    }
}

function move(event) {

    if (typeof(element.mouseup) == "undefined")
        document.addEventListener("mouseup", drop, false);
    //Prevents redundantly adding the same event handler repeatedly

    element.style.left = event.clientX - posX + "px";
    element.style.top = event.clientY - posY + "px";
}    

function drop() {
    document.removeEventListener("mousemove", move, false);
    document.removeEventListener("mouseup", drop, false);
    //alert("DEBUG_DROP");
}    

这里是html:

<body>

<p class="square">Thing One</p>
<p class="square">Thing Two</p>

</body>

这是css:

/* CSS Document */

.square {
    position: relative;
    width: 100px;
    height: 100px;
    background: red;
}

p {
    padding: 0px;
    margin: 0px;
}

感谢大家的宝贵时间!非常感谢!

Thank you all for your time! I greatly appreciate it!

推荐答案

这里有两个不同的问题需要考虑:

There are two separate issues to consider here:

  1. 如何获取页面上元素的位置?
  2. 当我为 lefttop 样式属性分配新值时会发生什么?
  1. How can I get the position of an element on the page?
  2. What happens when I assign new values to the left and top style properties?

第一个问题的答案取决于对element.offsetLeftelement.offsetTop的理解.这些属性给出了相对于 element.offsetParent 的偏移量,定义为最近的(包含层次结构中最近的)定位的包含元素".

The answer to the first question relies on an understanding of element.offsetLeft and element.offsetTop. These properties give the offset relative to element.offsetParent which is defined as "the closest (nearest in the containment hierarchy) positioned containing element".

在您的文档中,这是 <body> 元素,因此它可以按您的预期工作.如果您将方块放在其他元素中,您会发现您的代码将停止工作.你需要的是一个函数来遍历包含元素的树并对每个偏移量求和,像这样:

In your document this is the <body> element, so it works as you expected. If you were to place your squares inside other elements you'd find that your code would stop working. What you'd need is a function to walk up the tree of containing elements and sum each of the offsets, like this:

function findPos(obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
}

这样使用:

var pos= findPos(element);
posX = event.clientX - pos.x;
posY = event.clientY - pos.y;

回答第二个问题需要了解相对定位的元素.相对定位的元素出现在它们通常出现在页面上的位置相对.当您为 topleft 赋值时,您并没有给出绝对值.您给出的位置被视为相对于布局中元素的原始位置.这是相对定位的特性,而不是错误.您可能想使用 position: absolute; 代替.

Answering the second question requires an understanding of relatively positioned elements. Elements that are positioned relatively appear in a position relative to where they would normally appear on the page. When you assign values to top and left you're not giving absolute values. You're giving positions that are treated as relative to the element's original position in the layout. This is a feature of relative positioning, not a bug. You probably want to use position: absolute; instead.

相关文章