title: svg drag and drop
body: <p>I've got an svg element with an <code>foreignObject</code> inside of it with some divs. I want to be able to drag that object. Only problem: I can't get it working.</p>
  
  <p>I've found a couple of SO answers and tried to implement them. But none of them worked because i did get the same error over and over again:</p>
  
  <pre><code>Uncaught TypeError: undefined is not a function 
  </code></pre>
  
  <p>or</p>
  
  <pre><code>evt is not defined
  </code></pre>
  
  <p>I've got to following code from <a href="http://svg-whiz.com/svg/DragAndDrop.svg" rel="nofollow noreferrer">this</a> website (pointed out by an SO answer ):</p>
  
  <pre><code>&lt;svg id="bewaar_holder" xmlns="http://www.w3.org/2000/svg" width="800" height="500" onload="Init(evt)" onmousedown="Grab(evt)" onmousemove="Drag(evt)" onmouseup="Drop(evt)"&gt;&lt;/svg&gt;
  
  var SVGDocument = null;
  var SVGRoot = null;
  
  var TrueCoords = null;
  var GrabPoint = null;
  var BackDrop = null;
  var DragTarget = null;
  
  function Init(evt) {
      SVGDocument = evt.target.ownerDocument;
      SVGRoot = SVGDocument.documentElement;
  
      // these svg points hold x and y values...
      //    very handy, but they do not display on the screen (just so you know)
      TrueCoords = SVGRoot.createSVGPoint();
      GrabPoint = SVGRoot.createSVGPoint();
  
      // this will serve as the canvas over which items are dragged.
      //    having the drag events occur on the mousemove over a backdrop
      //    (instead of the dragged element) prevents the dragged element
      //    from being inadvertantly dropped when the mouse is moved rapidly
      BackDrop = SVGDocument.getElementById('BackDrop');
  }
  
  function Grab(evt) {
      // find out which element we moused down on
      var targetElement = evt.target;
  
      // you cannot drag the background itself, so ignore any attempts to mouse down on it
      if (BackDrop != targetElement) {
          //set the item moused down on as the element to be dragged
          DragTarget = targetElement;
  
          // move this element to the "top" of the display, so it is (almost)
          //    always over other elements (exception: in this case, elements that are
          //    "in the folder" (children of the folder group) with only maintain
          //    hierarchy within that group
          DragTarget.parentNode.appendChild(DragTarget);
  
          // turn off all pointer events to the dragged element, this does 2 things:
          //    1) allows us to drag text elements without selecting the text
          //    2) allows us to find out where the dragged element is dropped (see Drop)
          DragTarget.setAttributeNS(null, 'pointer-events', 'none');
  
          // we need to find the current position and translation of the grabbed element,
          //    so that we only apply the differential between the current location
          //    and the new location
          var transMatrix = DragTarget.getCTM();
          GrabPoint.x = TrueCoords.x - Number(transMatrix.e);
          GrabPoint.y = TrueCoords.y - Number(transMatrix.f);
  
      }
  };
  
  
  function Drag(evt) {
      // account for zooming and panning
      GetTrueCoords(evt);
  
      // if we don't currently have an element in tow, don't do anything
      if (DragTarget) {
          // account for the offset between the element's origin and the
          //    exact place we grabbed it... this way, the drag will look more natural
          var newX = TrueCoords.x - GrabPoint.x;
          var newY = TrueCoords.y - GrabPoint.y;
  
          // apply a new tranform translation to the dragged element, to display
          //    it in its new location
          DragTarget.setAttributeNS(null, 'transform', 'translate(' + newX + ',' + newY + ')');
      }
  };
  
  
  function Drop(evt) {
      // if we aren't currently dragging an element, don't do anything
      if (DragTarget) {
          // since the element currently being dragged has its pointer-events turned off,
          //    we are afforded the opportunity to find out the element it's being dropped on
          var targetElement = evt.target;
  
          // turn the pointer-events back on, so we can grab this item later
          DragTarget.setAttributeNS(null, 'pointer-events', 'all');
          if ('Folder' == targetElement.parentNode.id) {
              // if the dragged element is dropped on an element that is a child
              //    of the folder group, it is inserted as a child of that group
              targetElement.parentNode.appendChild(DragTarget);
              alert(DragTarget.id + ' has been dropped into a folder, and has been inserted as a child of the containing group.');
          } else {
              // for this example, you cannot drag an item out of the folder once it's in there;
              //    however, you could just as easily do so here
              alert(DragTarget.id + ' has been dropped on top of ' + targetElement.id);
          }
  
          // set the global variable to null, so nothing will be dragged until we
          //    grab the next element
          DragTarget = null;
      }
  };
  
  
  function GetTrueCoords(evt) {
      // find the current zoom level and pan setting, and adjust the reported
      //    mouse position accordingly
      var newScale = SVGRoot.currentScale;
      var translation = SVGRoot.currentTranslate;
      TrueCoords.x = (evt.clientX - translation.x) / newScale;
      TrueCoords.y = (evt.clientY - translation.y) / newScale;
  };
  </code></pre>
  
  <p>But i get this error:</p>
  
  <pre><code>Uncaught TypeError: undefined is not a function 
  on line: TrueCoords = SVGRoot.createSVGPoint();
  </code></pre>
  
  <p>Chrome debugger gives the following output when i log the <code>evt</code> value:
  <img src="https://i.stack.imgur.com/O6oHv.png" alt="enter image description here"></p>
  
  <p>And there's something i don't understand... In the first row <code>srcElement</code> do got an value,but when i expand the event, it doesn't got an <code>srcElement</code> anymore...</p>
  
  <p>So i'm out of clues. I've never worked with svg before and i'm no JS guru. So i hope that you guys know what i do wrong...</p>
  
  <p><a href="http://jsfiddle.net/3nufp/" rel="nofollow noreferrer">Here's an JSFiddle</a></p>