使用jQuery UI拖动之前重新定位元素

时间:2013-12-20 20:55:17

标签: jquery jquery-ui jquery-ui-draggable

这是尝试解决拖动元素与网格对齐的问题(我在之前的问题中概述了这一点 - Getting jQuery draggable to snap to specific grid

到目前为止,我已经确定问题是jQuery在调用.draggable()时计算元素的位置,并相对于元素创建网格,而不是相对于元素的父元素(这将更直观)。

在以下解决方案中,我们看到3个框:

  • 框1 从0,0开始,因此将与父元素的网格对齐。
  • 方框2 从未与网格对齐的点开始,因此在拖动时永远不会与其对齐。
  • 方框3 也从与网格不对齐的点开始,但在这种情况下,我们捕获鼠标按下事件,并将元素重新定位到最近的网格点,然后才对我们致电draggable()

选项3可以工作,因为元素现在将与网格对齐。问题是,它需要两个鼠标事件:一个用于重新定位元素,并且只有在下一个mousedown事件(在它变为黄色之后)才会实际拖动。

我怎样才能重做这个元素,以便重新定位元素,然后调用.draggable(),只需一个mousedown事件?

Aligning drag elements to grid

http://jsfiddle.net/8RnBf/34/

JS:

$('#box-1').draggable({
    grid: [ 20,20 ] 
});
$('#box-2').draggable({
    grid: [ 20,20 ] 
});

var isDraggable = false;
$('#box-3').mousedown(function(e){

    console.log('MOUSE DOWN');

    if (isDraggable == false) {
        var $this = $(this);

        // Reposition to nearest grid position:
        currentX = parseInt($this.css('left'));
        currentY = parseInt($this.css('top'));
        nearestGridX = Math.round(currentX/20) * 20;
        nearestGridY = Math.round(currentY/20) * 20;
        $this.css({left:nearestGridX+'px',top:nearestGridY+'px'});

        // Turn yellow:
        $this.css({background:'yellow'});

        // Make draggable:
        isDraggable = true;
        $this.draggable({
                grid: [ 20,20 ],
                start: function( event, ui ) {
                    console.log('START');
                }  
        });
        $this.trigger("mousedown");
    }

});

2 个答案:

答案 0 :(得分:8)

Live Demo

您可以比我猜想的更容易实现自定义网格功能。这应该简化了一些事情,因为您不必担心重新定位,然后使用jQuery UI的网格。

// Custom grid
$('#box-3').draggable({
    drag: function( event, ui ) {
        var snapTolerance = $(this).draggable('option', 'snapTolerance');
        var topRemainder = ui.position.top % 20;
        var leftRemainder = ui.position.left % 20;

        if (topRemainder <= snapTolerance) {
            ui.position.top = ui.position.top - topRemainder;
        }

        if (leftRemainder <= snapTolerance) {
            ui.position.left = ui.position.left - leftRemainder;
        }
    }  
});

另外,according to Scott Gonzalez,网格选项将来会消失,因为它本身就可以实现的那种微不足道的事情,所以这也为你的未来做好了准备。

答案 1 :(得分:3)

不是仅仅将事件类型作为触发器方法的参数传递,而是传递事件:

DEMO

$this.trigger(e);