13

Is there any possibility of receiving drag and drop events from SVG elements within a web page?

I tried the Google Closure library, to no avail.

Specifically, suppose my page contains

<ul id = "list">
  <li class="item" id="item1">foo</li>
  <li class="item">bar</li>
  <li class="item">baz</li>
</ul>

And my script contains (Clojurescript/C2)

(let [items (select-all ".item")
      lst (select "#list")
      target (fx/DragDrop. lst nil)]
  (dorun (map
    (fn [item]
      (let [source (fx/DragDrop. item nil)]
        (. source (addTarget target))
        (. source (init))))
    items))
  (. target (init)))

Then I do get a drag image (ghost), although I do not manage to receive drag events e.g. by doing

(on-raw "#item1" :dragstart (fn [e] (.log js/console (str "dragstart " e))))

Using similar code for SVG elements, I do not even get a ghost...

Any hints?

Thanks

Rom1
  • 3,167
  • 2
  • 22
  • 39

2 Answers2

23

Drag events are not supported on SVG Elements: http://www.w3.org/TR/SVG/svgdom.html#RelationshipWithDOM2Events.

You can fake the drag events with mouse events, see http://svg-whiz.com/svg/DragAndDrop.svg (view the source).

methodofaction
  • 70,885
  • 21
  • 151
  • 164
  • 1
    I know that this is not part of the standard, but I had hoped that a few browsers would start supporting it, and/or that a JS library encapsulating drag-and-drop for SVG would be available... Thanks for the example though! – Rom1 Sep 06 '12 at 07:51
  • 1
    Opera does support drag events on svg elements (same as for other HTML5 elements). – Erik Dahlström Sep 06 '12 at 08:26
  • Indeed it does! The issue is that my code, or C2, or Google closure and Opera do not seem to get along very well (I get strange errors related to `webkitMatchesSelector` or something...). Do you know if other browsers will follow suit? – Rom1 Sep 06 '12 at 12:22
  • Also, it seems that Chromium does fire at least a few drag events, but does not draw ghosts. Is there a way of troubleshooting this? – Rom1 Sep 06 '12 at 12:51
  • hmm, mouse events for drag and drop are not even handled on android. You may want to use `pointerevent` instead, which according to documentation should be a merge of mouse events and touch events. But still no success. then tried `style="touch-action: none"` to surpress default browser pinching behavior of android. But still ... no succes. – bvdb Apr 12 '19 at 08:05
2

You can always implement it. Basically, you have to check if the element is touching another one when you are dragging:

this.isTouching = function(element){
        if(this.x <= element.x && element.x <= (this.x + this.width) && 
           this.y <= element.y && element.y <= (this.y + this.height)){
           return true;
        }else{
            return false;
        }
    };

And it works in all browsers. Hope it helps :)

Ricardo Anjos
  • 1,417
  • 18
  • 22