Jquery Draggable - 中心光标垂直

时间:2011-04-21 22:08:12

标签: javascript jquery html draggable

我正在开发我的第一个JQuery项目,而且我遇到了一些障碍。我试图允许拖动和放大删除一组嵌套列表(ul)的重新排序。除了定位之外,一切都在工作。目标是使可拖动的相对于光标垂直居中(水平移动受到限制),以便可以容易地丢弃具有嵌套在其中的元素的li。这是相关的JS:

$(function() {
$( ".organizerlink" ).draggable({ axis: "y",
    containment:"#organizer",
    scroll: false ,
    helper: "original",
    revert: "invalid",
    cursorAt: { top: Math.round($(this).outerHeight() / 2)}
});

和HTML:

<ul id="organizer">
<li class="organizerTarget">&nbsp</li>
<li class="organizerlink" id="dbid-1">Page
    <ul><li class="organizerTarget organizerNewParent">&nbsp;</li></ul>
</li>
<li class="organizerTarget">&nbsp</li>
<li class="organizerlink" id="dbid-2">About
    <ul>
        <li class='organizerTarget'>&nbsp;</li>
        <li class='organizerlink' id="dbid-3">Another Page<ul><li class="organizerTarget organizerNewParent">&nbsp;</li></ul></li>
        <li class='organizerTarget'>&nbsp;</li>
        <li class='organizerlink' id="dbid-4">Example<ul><li class="organizerTarget organizerNewParent">&nbsp;</li></ul></li>
    </ul>
</li>
<li class="organizerTarget">&nbsp</li>
<li class="organizerlink" id="dbid-27">Stuff
    <ul><li class="organizerTarget organizerNewParent">&nbsp;</li></ul>
</li>

我已经尝试过的一些东西:

  • 将cursorAt设置为$(this).height() - 没有用,我猜高度()会拉高css高度,但是它们没有明确定义所以它跳转到0
  • 将它设置为outerHeight()会在firebug中给出一个错误“elem.style is undefined”

我知道在jquery中存在outerHeight元素,并且基于API doc它似乎可以自动计算,即使CSS未定义,所以我认为这是正确的方法去,也许$(这个)只是寻找它的错误点。

6 个答案:

答案 0 :(得分:8)

在我拿起它们之后,我也想把我的可拖动物体放在中心位置。我的解决方案:

$(".dragme").draggable({ 
    start: function(event, ui) { 
        $(this).draggable("option", "cursorAt", {
            left: Math.floor(this.clientWidth / 2),
            top: Math.floor(this.clientHeight / 2)
        }); 
    }
});

答案 1 :(得分:6)

解决了最初的问题,请参阅我最初发帖的评论。

编辑:

Tolerance option “指针”:鼠标指针与其他项目重叠。

$(".sortable").sortable({
    containment: "parent",
    tolerance: "pointer"
});

答案 2 :(得分:5)

如果draggable有辅助对象,这可以正常工作。只需将它放在draggable的start方法中,如下面的代码。

start: function(event, ui) { 
  $(this).draggable("option", "cursorAt", {
    left: Math.floor(ui.helper.width() / 2),
    top: Math.floor(ui.helper.height() / 2)
  }); 
}

答案 3 :(得分:5)

我只是花了几个小时把头撞在墙上试图让这个工作可靠,所以我想我会发布解决方案:)

<强>问题: Draggable无法将cursorAt设置为克隆&#39;在动态值实例化期间(即可变大小的可拖动代理的中心)拖动,因为ui.helper还没有被创建!您可以在启动处理程序中设置它,但它不适用于第一次拖动。

<强>解决方案: 将cursorAt设置为start,但也可以手动覆盖连续发生的拖动事件的ui.position。使用firstRun布尔值,可以防止它不必要地运行。您必须将默认cursorAt设置为左上角才能重新定位。

享受!

$jobs.each( function( index, element ) {
    var $el = $(element),
        firstRun = true;

    /*
     * jQuery UI Draggable
     * See @link: http://api.jqueryui.com/draggable/
     *
     * Note that for clone drags, the first drag cannot center the proxy because ui.helper hasn't been created yet
     * so need to set it manually for first drag. Subsequent drags can use the cursorAt property.
     * See my @link: 
     */
    $el.draggable({
        cursorAt : [0, 0],          // Set origin then update dynamically
        drag : function( evt, ui ) { // Fires after start event, and continuously during drag
            if ( firstRun ) {
                // Reset proxy position here since cursorAt cannot be set for 
                ui.position.left -= Math.floor( ui.helper.width()/ 2 );
                ui.position.top -= Math.floor( ui.helper.height()/ 2 );
            };
        },
        helper : 'clone',
        start : function( evt, ui ) { // Fires once
            if ( firstRun ) {
                // Center proxy relative to cursor for future drags
                $(this).draggable( 'option', 'cursorAt', {
                    left : Math.floor( ui.helper.width()/ 2 ),
                    top : Math.floor( ui.helper.height()/ 2 )
                });
            };

            // Set cursor ( 'cursor' option just applies style to <body> )
            ui.helper.css( 'cursor', 'move' );
        },
        stop : function( evt, ui ) { // Fires once
            if ( firstRun ) {
                firstRun = false;
            };
        }
    });

答案 4 :(得分:1)

在多次可拖动对象的情况下Goz的回答对我不起作用,所以这里是我的解决方案而不使用cursorAt选项

setTimeout
var offsetX = null;
var offsetY = null;
$(".item").draggable({
  helper:"clone",
  start:function(e,ui){
    offsetX=null;
    offsetY=null;
  },
  drag:function(e,ui){
    if(offsetX===null){
      offsetX = e.clientX-ui.offset.left;
      offsetY = e.clientY-ui.offset.top;
    }
    ui.position.left += offsetX - Math.floor( ui.helper.outerWidth()/ 2 );
    ui.position.top += offsetY - Math.floor( ui.helper.outerHeight()/ 2 );
            
  }
});
.desk{
  width:300px;
  height:300px;
  border:2px dashed gray;
}

.item {
  padding:8px;
  margin:2px;
  border:1px solid blue;
  background: rgba(0,0,80,.3);
  display:inline-block;
}

答案 5 :(得分:1)

@yuri gor:

您的答案对我有用,但是您可以从开始就设置偏移量:

    var offsetX = null;
    var offsetY = null;
    $(".item").draggable({
      helper:"clone",
      start:function(e,ui){
        offsetX = e.clientX-ui.offset.left;
        offsetY = e.clientY-ui.offset.top;
      },
      drag:function(e,ui){
        ui.position.left += offsetX - Math.floor( ui.helper.outerWidth()/ 2 );
        ui.position.top += offsetY - Math.floor( ui.helper.outerHeight()/ 2 );   
     }
    });