I have a little tool on a web page that can be clicked and dragged along a horizontal line. First I had the drag handle as an img. I had some problems with layout and realised later that it would probably be better to use a div with an img background.
So I changed the drag handle to use a div, and I discovered a pretty obvious error in my javascript code. I had the onMove and onUp events attached to the handle itself. So for example, if I clicked on the drag handle div and then moved my mouse upwards out of the div (as the div only moves left and right), it then doesn't catch the onUp or onMove events.
But the thing I don't understand, is why it worked perfectly when I was usin开发者_开发问答g an img tag. Is this a bug or is there something funny about images that makes them behave this way? Is it future-safe to leave use an img and leave the code as is?
When drag starts (
onDown
oronClick
), you should actually dynamically attachonUp
andonMove
events todocument
instead of handle. Just don't forget to clear themonUp
.However, there should be no difference between
<img>
and<div>
in this case.
-- EDIT --
I stand corrected. Seems, there is slight difference in img and div handling in FF since FF3. It enables you to drag images to your computer, but we can get around it :).
Anyway, I have made some slight modifications to your script, cleaned it up a bit, and it should work now in all browsers. I have tested it on my computer with Firefox 3.5.5, Safari 4.0.3, Google Chrome, and Opera 10.1.
However, I don't have a way to test it on IE, so please report results.
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Page Title</title>
<script>
window.onload = function() { //After page is loaded this script will start automaticly
var divEl = document.getElementById("myDiv"); // Locate element with id "myDiv"
var imgEl = document.getElementById("myImg"); // Locate element with id "myImg"
divEl.onmousedown = onDown; // Assign funnction to event mousedown on "myDiv"
imgEl.onmousedown = onDown; // Assign funnction to event mousedown on "myImg"
function onDown(e) { // Mouse is down, long live the mouse :)
$el = this;
if (e.preventDefault) { e.preventDefault(e); } // This prevents default "drag image" behaivour
window.onmousemove = function(e) { // Assign function onmousemove to window
this.onmouseup = function(e) { // When we do a mouseup anywhere on window
window.onmousemove = undefined; // We clear onmouse from window
window.onmouseup = undefined; // We clear onmouseup from window
}
/* Part borowed from http://www.quirksmode.org/js/events_properties.html */
if (e.pageX) { posx = e.pageX; } // In case it is a normal browser
else if (e.clientX) { // In case it is IE
posx = e.clientX + document.body.scrollLeft+document.documentElement.scrollLeft;
}
/* End of borowed part */
$el.style.left = posx-parseInt($el.offsetWidth)/2+"px"; // Move this element to where mouse is
}
}
}
</script>
<style>
#myImg, #myDiv { display: block; position: relative; left: 0; width: 100px; height: 50px; }
#myImg { border: 1px solid red; }
#myDiv { border: 1px solid blue; background-color: lime;}
</style>
</head>
<body>
<img src="some_image.png" alt="my img" id="myImg">
<div id="myDiv">My div</div>
</body>
</html>
Ah, yes. CSS & JS in this example are in HTML only for testing purposes. In real code it is suggested you separate them to their own files.
Good luck :)
I'm still not sure what was causing the original behaviour in IE, but I've rewritten as Krule's suggestion and there is still a problem with Mozilla handling img tags differently to div tags. Here's an example, works fine in IE, doesn't work properly in Mozilla:
<script language="javascript" type="text/JavaScript">
var elem = null;
var downX = null;
var elemX = null;
function onDown(e) {
var ev = window.event ? window.event : e;
elem = window.event ? ev.srcElement : ev.target;
downX = ev.clientX;
elemX = parseInt(elem.style.left);
document.onmousemove = onMove;
document.onmouseup = onUp;
}
function onMove(e) {
var ev = window.event ? window.event : e;
elem.style.left = elemX + ev.clientX - downX + "px";
}
function onUp() {
document.onmousemove = null;
document.onmouseup = null;
}
</script>
<img src="" alt="my img" id="myImg" onmousedown="onDown(event);" style="position:relative; left:0px; width:100px; height:50px; border: solid 1px red;" />
<br />
<br />
<div onmousedown="onDown(event);" style="position:relative; left:0px; width:100px; height:50px; background-color:Lime; border: solid 1px blue;"><div>
Not sure if there is a way to override this behaviour, or if I'm going to have to rewrite everything yet again to use div instead of img.
精彩评论