views:

633

answers:

5

I am trying to make an image draggable but drag a clone of the image (rather than the image itself). The copy seems to be working fine but the onmousemove trigger doesn't seem to fire until the onmouseup trigger has fired. I wouldn't think this is how things worked.

Working Code Below

var Draggable = {
  obj : null,
  clone : null,
  lastMessageSent : null,

  init : function(o) {
    o.style.cursor = "move";
    o.onmousedown = function(e) {
      Draggable.obj = this;
      Draggable.start(e);
    };
  },

  start : function(e) {
    e.preventDefault();

    Draggable.obj.style.cursor = "move";
    Draggable.createClone();

    window.onmousemove = function(e) { Draggable.beginDrag(e) };
    window.onmouseup = function(e) { Draggable.endDrag(e) };
  },

  createClone : function() {
    Draggable.clone = Draggable.obj.cloneNode(true);
    Draggable.clone.style.position = "absolute";
    Draggable.clone.style.top = "-800px";
    Draggable.clone.style.left = "-800px";
    Draggable.clone.style.zIndex = "90000";
    Draggable.clone.style.opacity = .35;
    Draggable.clone.id = "dragClone";

    document.body.appendChild(Draggable.clone);
  },

  beginDrag : function(e) {
    var scrollTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
    Draggable.clone.style.top = (e.clientY - 40 + scrollTop) + "px";
    Draggable.clone.style.left = (e.clientX - 40) + "px";
  },

  endDrag : function (e) {
    window.onmousemove = window.onmouseup = null;
    Draggable.obj.style.cursor = "normal";
    Draggable.clone.parentNode.removeChild(Draggable.clone);
  },

};


window.onload = function() { Draggable.init(document.getElementById("monkey")) };
A: 

Have you tried using setCapture on the documentElement (html tag)?

start : function() 
{    
    Draggable.createClone();
    documentElement.setCapture();
    documentElement.onmousemove = Draggable.beginDrag;
    documentElement.onmouseup = Draggable.endDrag;
},

endDrag : function () 
{
    documentElement.releaseCapture();
    documentElement.onmousemove = null;  
}

This would make all mouse events be captured by the documentElement. You can't use setCapture on the document object, although the events should still bubble up to it. See the MSDN documentation for setCapture.

Andy E
setCapture won't work as it isn't part of standard javascript. Thanks for the suggestion though.
powerfulninja
Sorry, my coding is usually limited to IE only.
Andy E
A: 

EDIT: I think the main problem is that you're putting the clone in front of the original. Why not try putting the clone behind and moving the original instead, since that is what the mousedown event first fires on?

Since my other answer wasn't cross browser compatible, I thought I'd have another go.

Instead of calling Draggable.start in the image onmousedown, use the document instead to capture an onmousedown that bubbles up from the image, checking the srcElement property of the event object to ensure the image was clicked.

The following is an example of how it might work, setting a draggable image's class attribute to contain the word "Draggable":

document.onmousedown = function ()
{
    if (/Draggable/.test(event.srcElement.className))
    {
        Draggable.obj = event.srcElement;
        Draggable.start;
    }
}

Just make sure the event bubbling doesn't get cancelled by anything on its way up the document.

Andy E
Still no love :(I've updated the source on the example page and it still does pretty much the same thing. I've added some firebug debugging in there and it appears be be calling the startDrag function once or twice after the mousedown and mousemove then just stops until you mouseup and mousedown again.Very bizare.
powerfulninja
I don't use Firefox but your code almost works in Chrome, IE throws a few errors. See my edit for another idea.
Andy E
A: 

The browsers default drag action was overriding the drag action I was trying to implement.

Solved by calling preventDefaults() on the mousedown event.

init : function(o) {
  Draggable.obj = o;
  o.onmousedown = Draggable.start;
},

start : function(e) {
  e.preventDefault();
  Draggable.createClone();
  document.onmousemove = Draggable.beginDrag;
  document.onmouseup = Draggable.endDrag;
},

more info: https://developer.mozilla.org/en/DOM/event.preventDefault

powerfulninja
A: 

powerfulninja,

I am working on the same scenario ,could you please post the full javascript code.

Thanks

vani
This is a comment, not a question.
Dykam
I've updated the original post with the working code. I removed some things that were specific to the app I built but the code posted should get you started.
powerfulninja
A: 

Thanks.. I am new to jquery ..I am getting syntax error for your code. My req is i need to clone a image on click and able to drag that cloned object .And should to able to delete it and capture the position of that image.After trying with ajax controls,now thought of using jquery. If you could suggest some article related to your code that will help me.

Vani
Again, this is a comment not an answer.
prodigitalson