javascriptdom-eventsdraggablescriptaculous

scriptaculous draggables: need to cancel onClick action when element is dragged


Thanks for the three excellent answers which all identified my problem of using "onclick = ..." instead of "observe( "click",..."

But the award for Accepted Answer has to go to Paolo Bergantino for the mechanism of adding a class name to mark the dragged element, which saved me some more work!


In my HTML I have a table with an image link on each row.

<table class="search_results">
  <tr>
     <td class="thumbnail"><a href="..."><img src="..." /></a></td>
...

An included Javascript file contains the code to make the images draggable:

$$( ".thumbnail a img" ).each(
  function( img )
  {
    new Draggable( img, {revert:true} );
  }
);

and a simple handler to detect the end of the drag

Draggables.addObserver({
  onEnd:function( eventName, draggable, event )
  {
    // alert ( eventName ); // leaving this in stops IE from following the link
    event.preventDefault(); // Does Not Work !!!
    // event.stop(); // Does Not Work either !!!
  }
});

My idea is that when the image is clicked the link should be followed but when it is dragged something else should happen.

In fact what happens is that when the image is dragged the handler is called but the link is still followed.

I guess that I'm cancelling the wrong event.

How can I prevent the link from being followed after the element is dragged?


edit: added event.stop after trying greystate's suggestion


I now have a basic solution that works for FireFox, Apache, etc. See my own answer below.

But I am still looking for a solution for IE7 (and hopefully IE6).

Another problem when dragging images in IE is that the image becomes detached from the mouse pointer when the tool tip appears, you have to release the mouse and click again on the image to re-acquire the drag. So I'm also looking for any ideas that might help resolve that problem.


Solution

  • <script>
    document.observe("dom:loaded", function() {
        $$( ".thumbnail a img" ).each(function(img) {
            new Draggable(img, {
                revert: true,
                onEnd: function(draggable, event) {
                    $(draggable.element).up('a').addClassName('been_dragged');
                }
            });
        });
    
        $$(".thumbnail a").each(function(a) {
            Event.observe(a, 'click', function(event) {
                var a = Event.findElement(event, 'a');
                if(a.hasClassName('been_dragged')) {
                    event.preventDefault();
                    // or do whatever else
                }
            });
        });
    });
    </script>
    

    Works for me on Firefox, IE. It kind of uses your 'marker' idea but I think marking an already dragged element with a class is more elegant than javascript variables.