Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Перетаскивание элементов на странице (https://javascript.ru/forum/misc/30285-peretaskivanie-ehlementov-na-stranice.html)

Антон Крамолов 30.07.2012 15:53

Перетаскивание элементов на странице
 
Вот мой пример http://pastehtml.com/view/c6ix3o7f1.html, все работает, но:

1) если у блока задан маргин, неправильно определяется положение блока относительно курсора, мое решение такое:

function getComputedStyleProperty(el, prop) {
    return window.getComputedStyle(el, null).getPropertyValue(prop);
}

function makeDraggable(el) {
    var drag, dx, dy;
    el.style.position = 'absolute';
    el.style.cursor = 'move';
    
    el.onmousedown = function(e) {
        var pos = findPosition(this);
        dx = pos[0] - e.clientX - parseInt(getComputedStyleProperty(this, 'margin-left'));
        dy = pos[1] - e.clientY - parseInt(getComputedStyleProperty(this, 'margin-top'));
        this.style.zIndex = maxZindex++;
        drag = true;
    }
    
    document.addEventListener('mouseup', function() {drag = false}, false);
    
    document.addEventListener('mousemove', function(e) {  
        if (drag) {
            el.style.left = e.clientX + dx + 'px';
            el.style.top = e.clientY + dy + 'px';
        }
    }, false);
}


Но как быть со значениями в em, pt?

2) Покритикуйте код

Geddar 30.07.2012 16:34

Если вы имеете margin родительского элемента, как это обычно бывает. То вам стоит пользоваться .offset()

Антон Крамолов 30.07.2012 16:43

мне не нужен jquery

Geddar 30.07.2012 16:52

вам его ни кто не навязывает - jquery это кроссбраузерный вариант.
offset в данном случае - проверенное решение

То что у вас нет в коде jq я заметил, не нужно так остро реагировать. Ни кто не мешает вам писать код самому

function ElemCoords(obj)
{
var curleft = 0;
var curtop = 0;
if (obj.offsetParent)
{
while (1)
{
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
if (!obj.offsetParent)
break;
obj=obj.offsetParent;
}
}
else if (obj.x || obj.y)
{
curleft += obj.x;
curtop += obj.y;
}
return {"x":curleft, "y":curtop};
}


http://javascript.ru/ui/offset

Антон Крамолов 30.07.2012 17:00

var pos = findPosition(this); // в функции такая строчка есть


А вот findPosition
function findPosition(el) {
    var pos = [0, 0];
    
    while (el) {
        pos[0] += el.offsetLeft;
        pos[1] += el.offsetTop;
        el = el.offsetParent;
    }
    
    return pos;
}


сравни со своей

Антон Крамолов 30.07.2012 19:18

/**
 * Делает доступным перетаскивание элемента. У перетаскиваемого элемента 
 * position должно быть установлено как absolute или fixed, внешние отступы 
 * должны быть заданы в пикселях.
 */
function makeDraggable(el, dragOptions) {
    var drag, dx, dy;
    
    el.addEventListener('mousedown', function(e) {
        var pos = findPosition(this);
        dx = pos[0] - e.clientX - parseInt(getComputedStyleProperty(this, 'margin-left'));
        dy = pos[1] - e.clientY - parseInt(getComputedStyleProperty(this, 'margin-top'));
        this.style.zIndex = maxZindex++;
        
        if (dragOptions.start) {
            dragOptions.start();
        }
        
        drag = true;
    }, false);
    
    document.addEventListener('mousemove', function(e) {  
        if (drag) {
            el.style.left = e.clientX + dx + 'px';
            el.style.top = e.clientY + dy + 'px';
            
            if (dragOptions.drag) {
                dragOptions.drag();
            }
        }
    }, false);
    
    document.addEventListener('mouseup', function() {
        if (dragOptions.end) {
            dragOptions.end();
        }
        
        drag = false
    }, false);


window.onload = function() {    
                var els = document.querySelectorAll('.dragbox');
                
                for (var i = 0; i < els.length; ++i) {
                    (function(el) {                     
                        makeDraggable(el, {
                            start: function() {
                                window.status = 'Start ' + el.style.backgroundColor;
                            },

                            drag: function() {                         
                                window.status = 'Drag ' + el.style.backgroundColor;
                            },

                            end: function() {
                                window.status = '';
                            }
                        });
                    })(els[i]);
                }
            }

Антон Крамолов 30.07.2012 21:22

function findPosition(el) {
    var x = y = 0;
    
    while (el) {
        x += el.offsetLeft;
        y += el.offsetTop;
        el = el.offsetParent;
    }
    
    return {x: x, y: y};
}


Опера подвела, в ней код некорректно работает, хз почему

http://gyazo.com/f424eda43a402109c2751106363876ef
http://gyazo.com/f4d5130668e14ee3457b8e5f326e6c6a

vadim5june 30.07.2012 21:46

если использовать getBoundingClientRect наверно все упростится
хотя не пробовал сам


Часовой пояс GMT +3, время: 18:13.