jQuery UI Sortable -- 如何取消拖动/排序项目的点击事件?
Posted
技术标签:
【中文标题】jQuery UI Sortable -- 如何取消拖动/排序项目的点击事件?【英文标题】:jQuery UI Sortable -- How can I cancel the click event on an item that's dragged/sorted? 【发布时间】:2010-10-31 03:18:22 【问题描述】:我有一个jQuery UI Sortable 列表。可排序的项目还附加了一个点击事件。有没有办法防止在我拖动项目后触发点击事件?
$().ready( function ()
$('#my_sortable').sortable(
update: function() console.log('update') ,
delay: 30
);
$('#my_sortable li').click(function ()
console.log('click');
);
);
#my_sortable li
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
【问题讨论】:
现在浏览器和 jqueryui 已经有一些时间来发展(补偿?)这种行为只在 Firefox (47.0) 中很明显。现代 Chrome 和 IE 在sortable
之后不会触发click
事件。
【参考方案1】:
我遇到了同样的问题,因为我的可排序项目包含三个或四个可点击项目(并且数量是可变的),动态绑定/取消绑定它们似乎并不是一个选项。但是,顺便说一句,我指定了
helper : 'clone'
选项,在界面方面与原始可排序的行为相同,但显然不会在拖动的项目上触发点击事件,从而解决了问题。它和其他任何东西一样都是一个 hack,但至少它是简短而容易的..
【讨论】:
Levi Crain 说:“"helper : 'clone'" 技巧在 chrome 中不起作用。onclick 事件永远不会触发。” 在 Firefox 16 中的工作就像一个魅力!谢谢 绝对是最佳答案!我喜欢简单的解决方案。上一个答案(选定答案)中的代码很聪明,但长期维护具有挑战性,尤其是对于试图找出聪明代码的新程序员。 我在组合 sortable 和 Magnific Popup 时遇到了问题。拖动元素后,将显示弹出窗口。在我为这个问题挣扎了几个小时之后,这就像上帝的礼物。 哇!这救了我的命!谢啦!谁知道会这么简单! :D【参考方案2】:如果你的 li 引用了 click 事件,你可以在 sortable update 方法中解绑它,然后使用 Event/one 重新绑定它。可以在重新绑定之前停止事件传播,从而防止触发您的原始点击处理程序。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
var myClick = function ()
console.log('click');
;
$().ready( function ()
$('#my_sortable').sortable(
update: function(event, ui)
ui.item.unbind("click");
ui.item.one("click", function (event)
console.log("one-time-click");
event.stopImmediatePropagation();
$(this).click(myClick);
);
console.log('update') ,
delay: 30
);
$('#my_sortable li').click(myClick);
);
</script>
<style type="text/css" media="screen">
#my_sortable li
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
【讨论】:
一个很好的实现! :) 这几乎是完美的,但是如果您执行失败的拖动,它仍然会执行单击功能。有什么想法吗? :(【参考方案3】:如果您出于某种原因不想使用 helper:'clone'
技巧,这对我有用。它取消了被拖动项目的点击事件。 jQuery 将 ui-sortable-helper
类添加到拖动的元素中。
$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event)
var cls = $(this).attr('class');
if (cls.match('ui-sortable-helper'))
return event.stopImmediatePropagation() || false;
【讨论】:
draggable
来自哪里?我以为这是关于sortable
。确实,$('.draggable')
对我来说是一个空列表。
´.sortable´ 是容器列表,里面的所有项目都是´.draggable´【参考方案4】:
$('.selector').draggable(
stop: function(event, ui)
// event.toElement is the element that was responsible
// for triggering this event. The handle, in case of a draggable.
$( event.toElement ).one('click', function(e) e.stopImmediatePropagation(); );
);
这是可行的,因为 "one-listeners" 在 "normal" 侦听器之前触发。因此,如果一个监听器停止传播,它将永远无法到达您之前设置的监听器。
【讨论】:
问题是如果浏览器在拖动过程中从不触发点击事件,这将阻止第一个“真正的”点击事件 对于 Firefox 42.0,我无法确认on
监听器是在 one
监听器之后触发的。事实上,我的on
侦听器仍然在我的one
侦听器之前被调用。【参考方案5】:
mercilor 的回答对我有一些警告。 click 事件实际上是在句柄元素上,而不是在排序的项目本身上。不幸的是,ui 对象没有在更新事件中为您提供对句柄的引用(对 jquery ui 的功能请求?)。所以我必须自己去拿把手。此外,我还必须调用 preventDefault 来停止点击操作。
update: function(ev, ui)
var handle = $(ui.item).find('h3');
handle.unbind("click");
handle.one("click", function (event)
event.stopImmediatePropagation();
event.preventDefault();
$(this).click(clickHandler);
);
// other update code ...
【讨论】:
【参考方案6】:更简单,使用 var 来了解元素何时被排序...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
$().ready( function ()
$('#my_sortable').sortable(
start: function()
sorting = true;
,
update: function()
console.log('update');
sorting = false;
,
delay: 30
);
$('#my_sortable li').click(function ()
if (typeof(sorting) == "undefined" || !sorting)
console.log('click');
);
);
</script>
<style type="text/css" media="screen">
#my_sortable li
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
【讨论】:
【参考方案7】:我们还可以在停止事件上使用标志,并在点击事件上检查该标志。
var isSortableCalled = false;
$('#my_sortable').sortable(
stop: function(event, ui)
isSortableCalled = true;
,
update: function() console.log('update') ,
delay: 30
);
$('#my_sortable li').click(function ()
if(!isSortableCalled)
console.log('click');
isSortableCalled = false;
);
【讨论】:
【参考方案8】:感谢Elte Hupkus;
helper: 'clone'
我已经实现了相同的,下面显示了一个示例。
$(document).ready(function()
$("#MenuListStyle").sortable(
helper:'clone',
revert:true
).disableSelection();
);
【讨论】:
【参考方案9】:一种解决方案是使用 live() 而不是普通绑定,但 Elte Hupkes 解决方案非常棒!!!!
【讨论】:
【参考方案10】:$('.menu_group tbody a').click(function()
link = $(this).attr('href');
window.location.href = link;
);
这个解决方案似乎对我有用。现在我可以点击可排序元素内的可点击内容。
注意:".menu_group tbody"
是 .sortable();
【讨论】:
以上是关于jQuery UI Sortable -- 如何取消拖动/排序项目的点击事件?的主要内容,如果未能解决你的问题,请参考以下文章
jquery UI sortable:如何更改“占位符”对象的外观?
jquery UI sortable:如何让原始可见直到下降?
jQuery UI 的 Sortable - 如何设置我的 'li.ui-state-highlight' 的样式?,总是出现白色 bg 颜色
如何让 jQuery UI 的 Draggable 和 Sortable 函数在 iPhone 上工作?