用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(); }); } });