用jQuery拖放防止点击事件

我有一个与jQuery draggabe页面上的元素。 这些元素有点击事件导航到另一个页面(例如普通链接)。

什么是最好的方式来防止点击放弃这样的元素,同时允许点击不拖放状态?

我有这种可sorting的元素的问题,但认为有一般的拖放解决scheme是很好的。

我已经为自己解决了这个问题。 之后发现Scriptaculous也存在相同的解决scheme,但也许有人有更好的方法来实现这一点。

这个解决scheme对我来说效果不错,不需要超时:(是的,我有些迂腐;-)

拖动开始时向元素添加标记类,例如“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 } }); 

解决scheme是添加点击处理程序,防止点击传播开始拖动。 然后在执行删除操作后删除该处理程序。 最后一个操作应该稍微延迟点击预防工作。

可sorting的解决scheme:

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

可拖动的解决scheme:

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

我想添加到这似乎阻止点击事件只适用于单击事件定义后拖动或sorting事件。 如果首先添加点击,则在拖动时被激活。

我发现使用标准的jQuery点击function:

$("#element").click(function(mouseEvent){ // click event });

在jQuery UI中工作得很好。 点击事件将不会在拖放时执行。 🙂

我有同样的问题,并尝试了多种方法,没有为我工作。

解决scheme1

 $('.item').click(function(e) { if ( $(this).is('.ui-draggable-dragging') ) return false; }); 

对我没有任何帮助。 拖动完成后,该项目将被点击。

解决scheme2 (由Tom de Boer撰写)

 $('.item').draggable( { stop: function(event, ui) { $( event.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); } ); } }); 

这工作得很好,但在一种情况下失败 – 当我要全屏onclick:

 var body = $('body')[0]; req = body.requestFullScreen || body.webkitRequestFullScreen || body.mozRequestFullScreen; req.call(body); 

解决scheme3 (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); } }) 

这对我不起作用。

解决scheme4-只有一个工作得很好

 $('.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; } 

Rocksolid ..

lex82的版本,但为.sortable()

  start: function(event, ui){ ui.item.find('.ui-widget-header').addClass('noclick'); }, 

你可能只需要:

  start: function(event, ui){ ui.item.addClass('noclick'); }, 

以下是我用于切换的内容:

 $("#datasign-widgets .ui-widget-header").click(function(){ if ($(this).hasClass('noclick')) { $(this).removeClass('noclick'); } else { $(this).next().slideToggle(); $(this).find('.ui-icon').toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick"); } }); 

萨沙的答案可能的select,而不是防止违约:

 var tmp_handler; .sortable({ start : function(event,ui){ tmp_handler = ui.item.data("events").click[0].handler; ui.item.off(); }, stop : function(event,ui){ setTimeout(function(){ui.item.on("click", tmp_handler)}, 300); }, 

通过阅读这个和几个线程,这是我去的解决scheme。

 var dragging = false; $("#sortable").mouseover(function() { $(this).parent().sortable({ start: function(event, ui) { dragging = true; }, stop: function(event, ui) { // Update Code here } }) }); $("#sortable").click(function(mouseEvent){ if (!dragging) { alert($(this).attr("id")); } else { dragging = false; } }); 

在jQuery UI中,被拖动的元素被赋予类“ui-draggable-dragging”。
因此,我们可以使用这个类来确定是否点击,只是延迟事件。
您不需要使用“开始”或“停止”callback函数,只需执行以下操作:

 $('#foo').on('mouseup', function () { if (! $(this).hasClass('ui-draggable-dragging')) { // your click function } }); 

这是由“mouseup”触发的,而不是“mousedown”或“click” – 所以有一点延迟,可能并不完美,但比其他解决scheme更容易。

你有没有尝试禁用链接使用event.preventDefault(); 在启动事件和重新启用拖动停止事件或使用解除绑定事件?

只是有点皱纹,以增加上面给出的答案。 我不得不做一个包含可拖动的SalesForce元素的div,但SalesForce元素通过一些VisualForce gobbledigook在html中定义了一个onclick动作。

显然,这违反了“拖动操作之后的定义点击操作”规则,所以作为一种解决方法,我重新定义了SalesForce元素的操作以触发“onDblClick”,并将此代码用于容器div:

 $(this).draggable({ zIndex: 999, revert: true, revertDuration: 0, start: function(event, ui) { $(this).addClass('noclick'); } }); $(this).click(function(){ if( $(this).hasClass('noclick')) { $(this).removeClass('noclick'); } else { $(this).children(":first").trigger('dblclick'); } }); 

父母的点击事件基本上隐藏了需要双击子元素,保持用户体验不变。

我试过这样的:

 var dragging = true; $(this).click(function(){ if(!dragging){ do str... } }); $(this).draggable({ start: function(event, ui) { dragging = true; }, stop: function(event, ui) { setTimeout(function(){dragging = false;}, 300); } }); 

在我的情况下,它的工作是这样的:

 $('#draggable').draggable({ start: function(event, ui) { $(event.toElement).one('click', function(e) { e.stopPropagation(); }); } });