2011-04-21 45 views
6

我正在開發我的第一個JQuery項目,並且遇到了一些障礙。我試圖允許拖放&刪除重新排序的一組嵌套列表(ul)。除了定位之外,一切都在起作用。目標是相對於光標垂直居中拖動(水平移動被限制),因此可以容易地將嵌有元素的li放置。下面是相關的JS:Jquery Draggable - 垂直中心的遊標

$(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爲$(本).height( ) - 沒有工作,我猜高度()拉動CSS高度,但他們沒有明確定義,所以它跳轉到0
  • 將其設置爲outerHeight()給我一個錯誤「elem.style是不確定的」螢火蟲

我知道outerHeight元素jQuery的存在,並基於API doc它會出現,它可以自動計算,即使CSS是未定義的,所以我認爲這是正確的方向,也許$(this)只是錯誤的地方尋找它。

+2

寬容:「指針」下droppable函數爲我提供了一個體面的解決方法。 – Sam 2011-04-21 23:42:05

回答

6

解決了最初的問題,請參閱我的初始帖子的評論。

編輯:

Tolerance option「指針」:鼠標指針重疊於其他項目。

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

我也想在拾取它們之後居中放置可拖動的物體。我的解決方案:

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

出於某種原因,當我把它放在啓動處理程序中時,這種方式不一致(可能這會導致jQuery UI的新版本中出現競態條件?),但在創建處理程序中效果很好。 – mmitchell 2013-02-25 19:39:09

+3

是的。這是不可靠的 - cursorAt必須正常設置(在start()之前)。 – T4NK3R 2013-10-17 10:35:02

5

如果可拖動有輔助對象,這可以正常工作。把它放在可拖動的開始方法如下代碼。

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

我認爲這是迄今爲止最可讀和最優雅的答案。 – rickcnagy 2015-04-08 03:14:16

5

我只花了幾個小時砸我的頭靠在牆上,試圖可靠地完成這項工作,所以我想我會發布的解決方案:)

問題: 可拖動不能在實例化動態值(即可變大小的可拖動代理的中心)期間,爲'克隆'拖動設置cursorAt,因爲ui.helper尚未創建!你可以在啓動處理程序中設置它,但它不適用於第一次拖動。

解決方案: 將cursorAt設置在開始位置,但也要手動覆蓋拖動事件的ui.position,這會持續發生。使用firstRun布爾值,可以防止它不必要地運行。您必須將默認光標設置爲左上角才能重新定位。

享受!

$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; 
      }; 
     } 
    }); 
+0

如果您花一些時間閱讀並將其應用於您的代碼,則此答案確實非常好。 – JREN 2016-03-04 10:43:34

+0

如果可拖動元素是可變寬度,請在拖動開始時刪除firstRun檢查。 – Emmanuel 2018-03-02 05:40:37

0

在乘拖動對象戈茲貝達的回答並沒有爲我工作,所以這裏的情況是我的解決方案,而無需使用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>