Тип позиционирования действительно влияет на мой JavaScript - PullRequest
1 голос
/ 27 февраля 2011

В настоящее время я создаю движок JavaScript с функцией перетаскивания. В настоящее время я делаю «ограничивающую» функцию, чтобы объект перетаскивания ограничивался контейнером с классом .bound. Когда я создаю перетаскиваемый объект, я также выясняю, имеет ли он границы:

function makeObj(e) {
    obj = new Object();
    obj.element = e;

    obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
    obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;

    obj.posX = event.clientX - e.offsetLeft;
    obj.posY = event.clientY - e.offsetTop;

    var curleft = curtop = 0;
    if (e.offsetParent) {
        do {
            curleft += e.offsetLeft;
            curtop += e.offsetTop;
            //alert(e.id + ":" + e.innerHTML);
            if(~e.className.search(/bound/)) {
                obj.boundX = curleft - obj.element.offsetLeft;
                obj.boundY = curtop - obj.element.offsetTop;
                return obj;
            }

        } while (e = e.offsetParent);
    }

    return obj;
}

Мои циклы работают, однако установка границ не работает.

Хотелось бы, чтобы этот html влиял на функцию:

<div id="center" class="bound">
    <h1>Hello World! <hr /></h1>
    <div id="box" class="bound">
        <p class="drag square" id="one"> One </p>
        <p class="drag square" id="two"> Two </p>
    </div>
</div>

Столько, сколько этот HTML:

<div id="center"> <!-- Difference is here -->
    <h1>Hello World! <hr /></h1>
    <div id="box" class="bound">
        <p class="drag square" id="one"> One </p>
        <p class="drag square" id="two"> Two </p>
    </div>
</div>

Разница заключается в классе .bound, в котором установлен position: relative.

Вот CSS:

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


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

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

.bound {
    position: relative;
}

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

#center {
    width: 500px;
    height: 300px;
    margin: auto;
    margin-top: 50px;
    background-color:#ccc;
    text-align: center;
    border-radius: 25px;
    -moz-border-radius: 25px;
}

#box {
    background-color: #FF3;
    height: 278px;
    border-radius: 0 0 25px 25px;
    -moz-border-radius: 0 0 25px 25px;
    opacity: 0.5;
}

Как мне сделать так, чтобы атрибут position: не влиял на работу двигателя - чтобы работала любая позиция. Абсолютный, Относительный, Статический, т. Д.? Как я могу сделать так, чтобы мои .drag объекты имели какое-либо расположение помимо абсолютного?

Я опубликую весь движок ниже (и ссылку jsfiddle) на всякий случай, если это будет полезно:

http://jsfiddle.net/Upvdm/1/

// JavaScript Document

var dragObj;

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

function down(event) {
    if(~event.target.className.search(/drag/)) {
        dragObj = makeObj(event.target);
        dragObj.element.style.zIndex="100";
        document.addEventListener("mousemove", freeMovement, false);
    }
}

function freeMovement(event) {

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

dragObj.element.style.left = Math.max(0, Math.min(event.clientX - dragObj.posX, dragObj.boundX)) + "px";
    dragObj.element.style.top = Math.max(0, Math.min(event.clientY - dragObj.posY, dragObj.boundY)) + "px";
}

function drop() {
    dragObj.element.style.zIndex="1";

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

function makeBoundlessObj(e) {
    obj = new Object();
    obj.element = e;

    obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
    obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;

    obj.posX = event.clientX - e.offsetLeft;
    obj.posY = event.clientY - e.offsetTop;

    return obj;
}

function makeObj(e) {
    obj = new Object();
    obj.element = e;

    obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
    obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;

    obj.posX = event.clientX - e.offsetLeft;
    obj.posY = event.clientY - e.offsetTop;

    var curleft = curtop = 0;
    if (e.offsetParent) {
        do {
            curleft += e.offsetLeft;
            curtop += e.offsetTop;
            //alert(e.id + ":" + e.innerHTML);
            if(~e.className.search(/bound/)) {
                obj.boundX = curleft - obj.element.offsetLeft;
                obj.boundY = curtop - obj.element.offsetTop;
                return obj;
            }

        } while (e = e.offsetParent);
    }

    return obj;
}

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

Большое спасибо за чтение и помощь!

1 Ответ

0 голосов
/ 27 февраля 2011
while (e = e.offsetParent);

Должно быть

while (e == e.offsetParent); //alternatively, use ===

В C-подобных языках (например, JavaScript) = означает «Поместите значение переменной справа в переменную слева». Однако == означает «Значения с обеих сторон совпадают?»

JavaScript рассматривает все, кроме нескольких вещей (например, 0, пустую строку, null и undefined), как ложное, а все остальное - как истинное. Таким образом, выражение e = e.offsetParent всегда будет возвращать true. Протестировал его, и он работает на отправленном вами примере JSFiddle.

...