开发者

jQuery Sortable -- remove a default behavior while dragging, restore after a drop

I've got a grid of pictures that I want to be able to drag/drop to sort. sortable() works great. The caveat is that I've also got the jQuery Fancybox plugin http://fancybox.net running which will open up a larger view of an image when clicked.

So you can click to start dragging, but as soon as you drop fancybox is triggered and the image enlarges.

I've tried s开发者_开发百科omething like this, but things get REALLY messed up (drag doesn't work at all anymore, my list gets rearranged all over the page, it's nasty):

$('#list').sortable({
  start:function(e,ui) {
    e.preventDefault();
  }
});

Tried with both start and stop but no luck. I've also tried unbinding the click handler for the items, but that didn't help either. Ideally I could sort of "hide" the fancybox handlers while dragging and then reinstate them after I drop. There may be a way to un-fancybox the whole list while dragging and then call $.fancybox() again to start it up, but there's gotta be an easier way...

Thanks for any help!


All right, I got it working! I was sure that kwicher's below would work but I had to tweak it a bit. I ended up having to swap back and forth between the fancybox callbacks and the sortable callbacks:

$('#list').sortable({
  start:function(e,ui) {
    ui.item.addClass('drag_sort');
  }
});

$('#list').fancybox({
  onStart:function(items,index,opts) {
    var obj = $(items[index]).parent()
    if (obj.hasClass('drag_sort')) {
      obj.removeClass('drag_sort');
      return false;
    }
  }
});

Putting the removeClass() in the stop callback of sortable wasn't working: apparently the sortable stop fires before the fancybox onStart and so the class was gone by the time fancybox went to look.

Note that the sortable targets the <li> in the list directly, but fancybox targets the <a> inside the list item. That's why I have to get the parent() in fancybox's onStart. Oh, and simply going return false in the onStart is enough to get fancybox to ignore that click!


I solved this problem with a fairly low tech approach for a project. Inside of start I would mark something saying that the current click is related to a drag and should be ignored.

Then in the code that gets triggered for a normal click event I would check to see if the current click was marked as for dragging. Super low tech example:

var clickIsForDragging = false;

$('#list li').click(function() {
  // Ignore dragging clicks
  if (clickIsForDragging) { 
    clickIsForDragging = false;
    return; 
  } 

  // Perform whatever normal click action 
});

$('#list').sortable({
  start:function(e,ui) {
    e.preventDefault();
    clickIsForDragging = true;
  }
});

Obviously, using globals is not ideal, but at this this demonstrates the concept. I am wondering if some property of the click event can be marked to say that its a dragging click. Maybe I will do some fiddling later and see.

I also saw another post on Stack Overflow that dealt with a similar issue and used unbinding and rebinding: jQuery UI Sortable -- How can I cancel the click event on an item that's dragged/sorted?


I have not tested it yet but in principle that should work:

$('#list').sortable({
 start:function(e,ui) {
 //e.preventDefault(); - I am not sure that would be necessary
 $('#list li').addClass('drag_sort');
}
stop:function(){
      $('#list li').removeClass('drag_sort');
}
});


$('#list li').fancybox({
 onStart:function(){
  if($(this).hasClass('drag_sort')){
   $.fancybox.cancel();
  }
 }
});

You could give it a try.

K

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜