My attempt at drag and drop

Dear forum

Rather than use a library, I have attempted to write my own attempt at a script that allows multiple elements to be dragged around the page. It starts by loading all divs into an array, and then forms a new array of only divs with the required class name. I believe this script doesn’t work for internet explorer, but I am not concerned by this.

As you will see if you run the code below, the script works well for divs containing text, but if I include an image inside a div, then the image will follow the mouse even if the button is released.

I have spent a whole day on this tiny script and really don’t know where to go from here! Could anybody shed some light on this please?





<script type="text/javascript"> 

var all_els=[]; 
var els=[]; 
var el; 

 window.onload = function() 

all_els=document.getElementsByTagName("div"); //an array of all div elements on page 
for(var i=0;i<all_els.length;i++){ 

if(all_els[i].className=='dragger') { els.push(all_els[i]);}   //just add those with the correct class name to our final array 


  for (el in els) 
  this.dragging=false;  //each element in the array is an object, so new properties e.g. dragging can be set.  Initially set the dragging property of each element to false 

  els[el].onmousedown=function() {this.dragging=true;} 
  els[el].onmouseup=function() {this.dragging=false;} 


 document.onmousemove = function(e) 

  for(el in els) 

   if (els[el].dragging==true) 
   els[el].style.left = e.clientX - els[el].offsetWidth/2 +'px'; 
   els[el] = e.clientY - els[el].offsetHeight/2+'px'; 


<title>Simple Drag</title> 

<div class="dragger"> Some text to drag </div> 
<div class="dragger"> Some other text to drag </div> 
<div class="dragger"> <img src=""></img> </div> 

The web browser is performing its default action when you drag an image.

Return false from the mouse up and down events to prevent that default action from occurring.

If you are having troubles I would recommend liking at the jQuery UI code.
I know the jQuery and then the ui library is huge but if you use the minify version on google server it shouldn’t be that bad to load and I personally like its functionality. It saves me time to work on the moreimportant elements of my site.

I haven’t tried a drag and drop exercise before, so will have a blast at this myself.

First thoughts, you don’t need all those ‘for in’ loops. For in by the way is the slowest method of javascript looping, in addition if hasOwnProperty isn’t checked it can return unpredictable results.

Maybe something along these lines instead

var all_els = document.getElementsByTagName("div"),
    dragRegX = /(^|\\s)dragger(\\s|$)/;

for( var i = 0, len = all_els.length; i < len; i++ ) { // assign length to a variable. More efficient.
  currEl = all_els[i];
  if ( dragRegX.test(currEl.className) ) {  
	currEl.dragging = false;
	currEl.onmousedown = function() { this.dragging = true; return false; }; // return false works for now
	currEl.onmouseup = function() { this.dragging = false; return false; }; //



Second thought is that I would look into using the event object instead for mousemove. For example event = event || window event, elem = || event.srcElement, if (elem.dragging == true) etc.

Thanks everybody for the replies.

I implemented pmw57’s reccomendation and now images are also dragging correctly too.

In other words, I changed the two mouseup/mousedown lines to:

els[el].onmousedown=function() {this.dragging=true; return false;}
els[el].onmouseup=function() {this.dragging=false; return false;}

I would like to understand a little more about why this works though !

RLM2008, you are absolutely right, an alternative (and probably better way) is to use / event.srcelement. I saw this in somebody elses code !

Now that I have my very basic method working, I can look toward a better method. RLM2008, I have put your code aside (with less loops) for a rainy day - I will need to try and understand Regx first !

Thanks again everybdoy , you really are the business !


It’s like when you do similar to the onclick event of links. Normally the web browser performs its own behaviour, and to prevent that default behaviour from occurring you have to return false from the event to prevent that default action.

With images, you can normally drag them from the web page and copy off to some other location. Because you don’t want the web browser messing with your own drag and drop thing, you need to tell the web browser “nuh uh, I got this”.

That makes sense, thank you. I have also just read up on returning true & false, in different contexts. And, as you say, return false can be used to prevent markup behaviour.

Thanks again for your help