Html5 arrastrar y soltar en el elemento svg

Estoy tratando de seguir el tutorial de arrastrar y soltar html5 aquí . No pude conseguir que el evento dragstart se registrara en el elemento rect . Si cambio el evento de draggable a mousedown , llama al controlador handleDragStart . Por favor ignore el registro en blanco adicional en el código.

JSFiddle aquí


     svg rect { cursor: move; }   

SVG/HTML 5 Example

loc.js

 $(document).ready(function() { function handleDragStart(e) { log("handleDragStart"); this.style.opacity = '0.4'; // this ==> e.target is the source node. }; var registercb = function () { $("#cvs > rect").each(function() { $(this).attr('draggable', 'true'); }); $("#cvs > rect").bind('dragstart', handleDragStart); $(window).mousedown(function (e) { }); $(window).mousemove(function (e) { }); $(window).mouseup(function (e) { log("mouseup"); }); }; function log() { if (window.console && window.console.log) window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' ')); }; registercb(); }); 

Sé que esta es una pregunta antigua. Llegué aquí desde esta otra pregunta que estaba marcada como un duplicado de esta, y quería agregar una posible solución que no requiera jQuery ni ninguna biblioteca, y que funcione en todos los navegadores principales. Se basa en este tutorial recomendado por @AmirHossein Mehrvarzi .

Esta pequeña solución no utiliza los eventos de arrastre, solo el mousedown , el mouseup y el mousemove . Así es como funciona:

  • Cuando el mouse está abajo en el rectángulo, guarda la posición del mouse y el elemento activo.
  • Cuando el mouse se mueve, las coordenadas del rectángulo se actualizan con la nueva posición del mouse.
  • Cuando el ratón está arriba, restablece el elemento activo.

Del código en la pregunta anterior:

 var selectedElement = null; var currentX = 0; var currentY = 0; $(document).ready(function() { function handleDragStart(e) { log("handleDragStart"); this.style.opacity = '0.4'; // this ==> e.target is the source node. }; var registercb = function () { $("#cvs > rect").mousedown(function (e) { // save the original values when the user clicks on the element currentX = e.clientX; currentY = e.clientY; selectedElement = e.target; }).mousemove(function (e) { // if there is an active element, move it around by updating its coordinates if (selectedElement) { var dx = parseInt(selectedElement.getAttribute("x")) + e.clientX - currentX; var dy = parseInt(selectedElement.getAttribute("y")) + e.clientY - currentY; currentX = e.clientX; currentY = e.clientY; selectedElement.setAttribute("x", dx); selectedElement.setAttribute("y", dy); } }).mouseup(function (e) { // deactivate element when the mouse is up selectedElement = null; }); }; function log() { if (window.console && window.console.log) window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' ')); }; registercb(); }); 
 rect { cursor: move; } 
  

SVG/HTML 5 Example

Este comportamiento puede ser causado por varias razones:

  • HTML 5 arrastrar y soltar es un desastre, de acuerdo con este artículo . Sé que es un poco más viejo, pero el problema todavía no se resuelve
  • jQuery no admite el modelo SVG DOM. Por lo tanto, algunas partes pueden funcionar, otras no (como offset() o width() ).

Definitivamente no me basaría en el soporte de arrastrar y soltar de HTML5 en este momento, sino más bien usar una biblioteca para manejar este problema. Si quieres trabajar con SVG, puedes probar Raphaël . Si también necesita jQuery, tal vez el complemento SVG sea ​​el camino a seguir. Tenga en cuenta que ambos proyectos no están desarrollados activamente en este momento. Sé que esta no es realmente una respuesta satisfactoria, pero también tuve que aprender que jQuery y SVG no van tan bien juntos. Esperemos que alguien me demuestre que está equivocado;).