Jquery Draggable - 垂直居中光标
Posted
技术标签:
【中文标题】Jquery Draggable - 垂直居中光标【英文标题】:Jquery Draggable - center cursorAt Vertically 【发布时间】:2011-08-10 15:42:28 【问题描述】:我正在开发我的第一个 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"> </li>
<li class="organizerlink" id="dbid-1">Page
<ul><li class="organizerTarget organizerNewParent"> </li></ul>
</li>
<li class="organizerTarget"> </li>
<li class="organizerlink" id="dbid-2">About
<ul>
<li class='organizerTarget'> </li>
<li class='organizerlink' id="dbid-3">Another Page<ul><li class="organizerTarget organizerNewParent"> </li></ul></li>
<li class='organizerTarget'> </li>
<li class='organizerlink' id="dbid-4">Example<ul><li class="organizerTarget organizerNewParent"> </li></ul></li>
</ul>
</li>
<li class="organizerTarget"> </li>
<li class="organizerlink" id="dbid-27">Stuff
<ul><li class="organizerTarget organizerNewParent"> </li></ul>
</li>
我已经尝试过的一些东西:
将 cursorAt 设置为 $(this).height() - 不起作用,我猜 height() 会拉入 css 高度,但它们没有明确定义,所以它会跳转到 0 将其设置为 outerHeight() 会在 firebug 中出现错误“elem.style is undefined”我知道outerHeight元素存在于jquery中,并且基于API doc它似乎可以自动计算,即使CSS未定义,所以我认为这是正确的方法,也许 $(this) 只是寻找它的错误位置。
【问题讨论】:
tolerance:"pointer" 在 droppable 函数下为我提供了一个不错的解决方法。 【参考方案1】:我还想在拾起可拖动对象后将它们居中。我的解决方案:
$(".dragme").draggable(
start: function(event, ui)
$(this).draggable("option", "cursorAt",
left: Math.floor(this.clientWidth / 2),
top: Math.floor(this.clientHeight / 2)
);
);
【讨论】:
由于某种原因,这对我来说在放入启动处理程序时工作不一致(可能这会导致较新版本的 jQuery UI 中的竞争条件?)但在创建处理程序中效果很好。 是的。这是不可靠的 - cursorAt 必须正常设置(在 start() 之前)。【参考方案2】:解决了最初的问题,请参阅我最初帖子的评论。
编辑:
Tolerance option“pointer”:鼠标指针与其他项目重叠。
$(".sortable").sortable(
containment: "parent",
tolerance: "pointer"
);
【讨论】:
【参考方案3】:如果可拖动对象具有辅助对象,则此方法可以正常工作。只需将它放在可拖动的启动方法中,如下代码。
start: function(event, ui)
$(this).draggable("option", "cursorAt",
left: Math.floor(ui.helper.width() / 2),
top: Math.floor(ui.helper.height() / 2)
);
【讨论】:
我认为这是迄今为止最具可读性和优雅的答案。【参考方案4】:我只是花了几个小时把头撞在墙上试图可靠地完成这项工作,所以我想我会发布解决方案:)
问题: Draggable 无法在实例化动态值(即可变大小的可拖动代理的中心)期间为“克隆”拖动设置 cursorAt,因为尚未创建 ui.helper!您可以在启动处理程序中设置它,但它不适用于第一次拖动。
解决方案: 在 start 内设置 cursorAt,但也手动覆盖连续发生的拖动事件的 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;
;
);
【讨论】:
如果您花一些时间阅读它并将其应用于您的代码,这个答案真的非常好。 删除firstRun
如果您的可拖动元素是可变宽度,则在拖动开始处签入。
如果 droppable 比 draggable 小,这个 firstRun 的东西不会像预期的那样工作!因为当可放置中心悬停可拖动但您希望它与光标悬停时,可拖动获得悬停焦点。我找到的完美解决方案in this thread【参考方案5】:
如果是多个可拖动对象,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>
【讨论】:
【参考方案6】:@yuri 戈尔:
你的回答对我有用,但你可以从一开始就开始偏移:
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 );
);
【讨论】:
是的,你是对的,我不记得我在想什么做这么复杂的初始化,也许是因为我的应用程序中的一些其他代码,这超出了本文的范围- p.以上是关于Jquery Draggable - 垂直居中光标的主要内容,如果未能解决你的问题,请参考以下文章