javascript - HTML/CSS 中的定位是如何工作的?

标签 javascript html css drag-and-drop

我正在尝试用 JavaScript 制作一个拖放引擎。现在,我添加了一个边界功能,它将把 .drag 对象捕获在其父元素内。然而,要做到这一点,我需要了解定位在 html 中是如何工作的,但我没有。谁能详细解释一下吗?

Javascript 引擎:

// JavaScript Document

var posX;
var posY;
var element;
var currentPos;

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

function drag(event) {
    if(~event.target.className.search(/drag/)) {
        element = event.target;
        element.style.zIndex="100";
        currentPos = findPos(element);
        posX = event.clientX -currentPos.x;
        posY = event.clientY -currentPos.y;
            if(~event.target.className.search(/bound/))
                document.addEventListener("mousemove", boundMovement, false);
            else
                document.addEventListener("mousemove", freeMovement, false);
    }
}

function freeMovement(event) { // This functions works

    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 boundMovement(event) { // This function doesn't work

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

    // Below logic is false- I wish to understand why =]
    currentPos = findPos(element.offsetParent);
    if((event.clientX - posX) <= currentPos.x)
        element.style.left = event.clientX - posX + "px";
    if((event.clientY - posY) <= currentPos.y)
        element.style.top = event.clientY - posY + "px";
}

function drop() {
    element.style.zIndex="1";
    document.removeEventListener("mousemove", boundMovement, false);
    document.removeEventListener("mousemove", freeMovement, false);
    document.removeEventListener("mouseup", drop, false);
    //alert("DEBUG_DROP");
}

function findPos(obj) { // Donated by `lwburk` on StackOverflow
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
}

这是我正在使用的 CSS:

@charset "utf-8";
/* CSS Document */

.drag {
    position: absolute;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
}

.bound {
    /* Class to signify that the drag_object can not leave the parent element */
    ;
}

.square {
    width: 100px;
    height: 100px;
    background: red;
    cursor:move;
}

p {
    padding: 0px;
    margin: 0px;
    outline-style: dotted;
    outline-color: #000;
    outline-width: 1px;
}

一些 HTML 示例:

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

请注意,我包含了 JavaScript,以便如果我对如何相对于我所编写的内容应用事物有疑问。另外,感谢大家的阅读和帮助。 StackOverflow 是学习如何使用 JavaScript 编码的绝佳资源。

编辑:

1) 我应该说我正在编写引擎来帮助我学习该语言。这是我学习 JavaScript 的第一周,我希望在使用库之前能够使用该语言进行编码。

2)例如,我真的希望有人解释一下偏移量在这里是如何工作的。我想知道如何不使用 position:absolute 来制作我的 JavaScript 引擎,而是使用 position:relative 以便元素可以堆叠在彼此之上等。

最佳答案

我已在 http://jsfiddle.net/vJ6r6/ 发布了解决方案.

首先,我将要拖动的元素嵌套在边界框内:

<div class="bound">Thing One
    <div class="drag square">Thing Two</div>
    <div class="drag square">Thing Three</div>
</div>

此外,我将它们变成了 div,因为 p 不能嵌套。 (不要忘记也更改样式声明。)

然后,我在边界框上设置样式:

<style>
.bound {
    margin: 100px;
    width: 400px;
    height: 400px;
    position: relative;
}
</style>

关键属性是position:relative,这会导致其中的元素相对于它定位,而不是相对于页面定位。 请注意,因为我使用的是相对定位,所以当您想要将元素保留在特定容器中时,此示例效果最佳。

我对 JavaScript 的更改更为彻底,所以这就是整个事情:

<script>
var dragInfo;

function down(event) {
    if (~event.target.className.search(/drag/)) {
        document.addEventListener("mouseup", drop, false);
        var t = event.target;
        t.style.zIndex = 100;
        dragInfo = {
            element: t,
            // record the bounds
            maxX: t.parentNode.offsetWidth - t.offsetWidth,
            maxY: t.parentNode.offsetHeight - t.offsetHeight,
            // we don't need findPos, because it's no longer relative to the page
            posX: event.clientX - t.offsetLeft,
            posY: event.clientY - t.offsetTop
        };
        document.addEventListener("mousemove", freeMovement, false);
    }
}

function freeMovement(event) {
    // the min and max calculations keep the X and Y within the bounds
    dragInfo.element.style.left = Math.max(0, Math.min(event.clientX - dragInfo.posX, dragInfo.maxX)) + "px";
    dragInfo.element.style.top = Math.max(0, Math.min(event.clientY - dragInfo.posY, dragInfo.maxY)) + "px";
}

function drop() {
    dragInfo.element.style.zIndex = 1;
    document.removeEventListener("mousemove", freeMovement, false);
    document.removeEventListener("mouseup", drop, false);
}

document.addEventListener("mousedown", down, false);
</script>

请注意这一行:

dragInfo.element.style.left = Math.max(0, Math.min(event.clientX - dragInfo.posX, dragInfo.maxX)) + 'px';

相当于:

var x = event.clientX - dragInfo.posX;
if (x < 0) x = 0;
if (x > dragInfo.maxX) x = dragInfo.maxX;
dragInfo.element.style.left = x + 'px';

关于javascript - HTML/CSS 中的定位是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5125023/

相关文章:

javascript - 星级评定系统(半星)

css - 使 flexbox 列使用可用宽度

javascript - 更改 Firefox 中的警报选项卡/窗口焦点

html - 将一个 div 水平对齐到左侧,一个标题对齐到中心,一个 div 水平对齐到右侧

javascript - jquery UI datepicker 没有显示在 html 输入文本上

html - 如何显示以 longblob 形式保存在数据库中的图像?

css - 如何风格化圆形Fontawesome图标背景?

css - 媒体查询确定 html 元素的大小?

javascript - 在 html img 标签中使用函数结果

javascript - 为什么 mongodb find() 从来没有得到我的回调