Jquery Draggable - 中心光标垂直

问题描述 投票:6回答:6

我正在开发我的第一个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”

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

javascript jquery html draggable
6个回答
8
投票

我也想在我拿起它们之后将我的可拖动物体居中。我的解决方案

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

6
投票

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

编辑:

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

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

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

5
投票

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

问题:在实例化动态值(即可变大小的可拖动代理的中心)期间,Draggable无法为“克隆”拖动设置cursorAt,因为还没有创建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;
            };
        }
    });

1
投票

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

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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="desk">
  <div class="item">Item 1</div>
  <div class="item" style="width:100px;">Item 2</div>
  <div class="item" style="height:50px;">Item 3</div>
</div>

1
投票

@ Yuri r:

你的答案对我有用,但是你可以从开始就看到偏移:

    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 );   
     }
    });
© www.soinside.com 2019 - 2024. All rights reserved.