JavaScript mouse drag program not working

Below is an html doc with an image of a car in the middle. I wrote some JavaScript code that is supposed to let you drag the car in the horizontal direction. In my mouseDrag(evt) function, the line of code shown below does not work. I need it to work so that the cursor stays at fixed distance from the image as it's being dragged:

car.style.left = mousePosition + distance + "px";

However, these two lines of test code surprisingly do work but don't produce the effect I want:

car.style.left = mousePosition + "px";
car.style.left = distance + "px";

The variables mousePosition and distance are numbers. The event handler for the mousemove event works for either mousePosition or distance, but not for the sum of the two. Why does the event handler respond to the numbers mousePosition and distance individually but not to the number mousePosition + distance?  You'll have to uncomment and run these three lines one at a time to see what I'm talking about.

<html> 
<head>   
<style> 
#car {
      position: absolute; 
      width: 200x; 
      height: 100px;     
	  top: 200px; 
	  left: 400px;
}
</style>
</head>
<body>   

<img id="car" src="http://nostarch.com/images/car.png"/> 

<script>  
var car = document.getElementById('car');    
car.addEventListener("mousemove", mouseDrag, false);  
 
function mouseDrag(evt){  
  var mousePosition = evt.clientX;  
  var carPosition = parseInt(getStyle(car, "left")); 
  var distance = carPosition - mousePosition;
  
  //car.style.left =  mousePosition + "px";   //works
  //car.style.left =  distance  + "px";       //works
  //car.style.left =  mousePosition + distance  + "px";   //doesn't work
}
  
function getStyle(object, styleName) {  
  return window.getComputedStyle(object, null).getPropertyValue(styleName); 
} 
</script>
</body>
</html> 

Open in new window

ArchimelAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Robert SchuttSoftware EngineerCommented:
It's not that the 3rd line doesn't work but you're putting the image right back in the place where it already was: you're setting left = mousePosition + distance but distance = carPosition - mousePosition so you're setting left = carPosition which is the current left position so there is no movement.

You should only calculate distance when the cursor first hits the image for example like this:
var car = document.getElementById('car');

var distance;
car.addEventListener("mouseenter", function(evt) {
    var mousePosition = evt.clientX;
    var carPosition = parseInt(getStyle(car, "left"));
    distance = carPosition - mousePosition;
}, false);

car.addEventListener("mousemove", mouseDrag, false);

function mouseDrag(evt){  
    var mousePosition = evt.clientX;
    car.style.left =  mousePosition + distance  + "px";
}

function getStyle(object, styleName) {
    return window.getComputedStyle(object, null).getPropertyValue(styleName);
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Robert SchuttSoftware EngineerCommented:
Here's a jsFiddle I used for testing: http://jsfiddle.net/bxuhrgeL/1/

PS: note that since the mousemove event is only attached to the image, it's easy to move off it and 'lose' contact. Not sure that is of any consequence but just noticed it after making some 'wild' moves...
0
ArchimelAuthor Commented:
I see my mistake now. Your "mouseenter" code starting on line 4 was the key to fixing the problem.  

Oddly enough though, when I changed "mouseenter" to "mousedown", it stopped working again. I'd really prefer "mousedown" so that the dragging occurs only while the mouse button is pressed. Is there anything extra I need to do to make "mousedown" work?
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Robert SchuttSoftware EngineerCommented:
That needs a bit more work. I tried adding a check on evt.buttons == 1 in the mouseDrag function but it only helped partially, I think it needs to be rewritten a bit to cater for that change. Did you also consider touch users or is that not an issue for you?
0
Robert SchuttSoftware EngineerCommented:
I had a look at it but stupid enough I can't get it to work like that. At some point I got it to work in IE but not Chrome (which is my main browser at the moment). It seems there is a problem with the browser taking over as a "drag" event. I added event cancel handlers and unselectable attributes but to no avail...

There is an example that works but somehow seems not straightforward enough (should be but is not) for me to build in to your current code: http://javascript.info/tutorial/mouse-events maybe worth to have a look at that yourself.
0
ArchimelAuthor Commented:
Thanks for the link. The drag-and-drop section with the soccer ball is exactly what I want. I'll work from this example.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.