我在页面上有可使用 jQuery 拖动的元素。这些元素是否具有导航到另一个页面的点击事件(例如普通链接)。
防止单击在放置此类元素时触发同时允许单击它不是拖放状态的最佳方法是什么?
我对可排序元素有这个问题,但认为有一个通用拖放的解决方案是很好的。
我已经为自己解决了这个问题。在那之后,我发现Scriptaculous 存在相同的解决方案,但也许有人有更好的方法来实现这一目标。
我在页面上有可使用 jQuery 拖动的元素。这些元素是否具有导航到另一个页面的点击事件(例如普通链接)。
防止单击在放置此类元素时触发同时允许单击它不是拖放状态的最佳方法是什么?
我对可排序元素有这个问题,但认为有一个通用拖放的解决方案是很好的。
我已经为自己解决了这个问题。在那之后,我发现Scriptaculous 存在相同的解决方案,但也许有人有更好的方法来实现这一目标。
一个对我来说效果很好并且不需要超时的解决方案:(是的,我有点迂腐;-)
我在拖动开始时向元素添加一个标记类,例如“noclick”。当元素被放置时,点击事件被触发——更准确地说,如果拖动结束,实际上它不必被放置到一个有效的目标上。在单击处理程序中,我删除标记类(如果存在),否则将正常处理单击。
$('your selector').draggable({
start: function(event, ui) {
$(this).addClass('noclick');
}
});
$('your selector').click(function(event) {
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');
}
else {
// actual click event code
}
});
解决方案是添加单击处理程序,以防止单击在拖动开始时传播。然后在执行 drop 后删除该处理程序。最后一个动作应该延迟一点,以便点击预防工作。
可排序的解决方案:
...
.sortable({
...
start: function(event, ui) {
ui.item.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.item.unbind("click.prevent");}, 300);
}
...
})
可拖动解决方案:
...
.draggable({
...
start: function(event, ui) {
ui.helper.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
}
...
})
我遇到了同样的问题并尝试了多种方法,但没有一种对我有用。
方案一
$('.item').click(function(e)
{
if ( $(this).is('.ui-draggable-dragging') ) return false;
});
对我没有任何作用。拖动完成后正在单击该项目。
解决方案 2(作者:Tom de Boer)
$('.item').draggable(
{
stop: function(event, ui)
{
$( event.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); } );
}
});
这工作得很好,但在一种情况下失败 - 当我全屏点击时:
var body = $('body')[0];
req = body.requestFullScreen || body.webkitRequestFullScreen || body.mozRequestFullScreen;
req.call(body);
解决方案 3(由 Sasha Yanovets)
$('.item').draggable({
start: function(event, ui) {
ui.helper.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
}
})
这对我不起作用。
解决方案 4 - 唯一一个运行良好的解决方案
$('.item').draggable(
{
});
$('.item').click(function(e)
{
});
是的,就是这样 - 正确的顺序可以解决问题 - 首先你需要绑定 draggable() 然后 click() 事件。即使我将全屏切换代码放在 click() 事件中,拖动时它仍然没有进入全屏。适合我!
我想补充一点,似乎只有在可拖动或可排序事件之后定义单击事件时,才能阻止单击事件。如果首先添加点击,它会在拖动时激活。
我真的不喜欢使用计时器或预防,所以我所做的是:
var el, dragged
el = $( '#some_element' );
el.on( 'mousedown', onMouseDown );
el.on( 'mouseup', onMouseUp );
el.draggable( { start: onStartDrag } );
onMouseDown = function( ) {
dragged = false;
}
onMouseUp = function( ) {
if( !dragged ) {
console.log('no drag, normal click')
}
}
onStartDrag = function( ) {
dragged = true;
}
坚如磐石..