问题
How does one set the position of an element? When the user drags an element (an image), I'd like to have it move synchronously. I see that my "mousemove" handler is being called. However I cannot get the element to actually move.
Here's the mousemove handler (the element being dragged is "overlay"):
function handleMouseMove (event)
{
var deltaX = event.movementX;
var deltaY = event.movementY;
var divOverlay = document.getElementById ("overlay");
var rect = divOverlay.getBoundingClientRect();
divOverlay.style.left = rect.x + deltaX;
divOverlay.style.top = rect.y + deltaY;
}
Here's the html for "overlay":
<div id="overlay">
... some other stuff ...
<img id="large" src="something.jpg" >
</div>
And the css:
#overlay {position:absolute; left:0; top:0}
It appears that the default drag action manifests, which is a shadow of "overlay" that moves with the mouse. But the element itself does not move.
回答1:
Not sure about your actual implementation. However this code works:
To do it using your code, here is the code. One obvious issue with your code is you need to add 'px' to your style.left and style.right. Also it is unknown how you actually handle the event from your code. Using this code, the element moves in a circle, you need to fix it but you get the idea.
var divOverlay = document.getElementById ("overlay");
var isDown = false;
divOverlay.addEventListener('mousedown', function(e) {
isDown = true;
}, true);
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
document.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
var rect = divOverlay.getBoundingClientRect();
divOverlay.style.left = rect.x + deltaX + 'px';
divOverlay.style.top = rect.x + deltaX + 'px';
}
}, true);
Below is another way of doing it. Codepen example
var offset = [0,0];
var divOverlay = document.getElementById ("overlay");
var isDown = false;
divOverlay.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
divOverlay.offsetLeft - e.clientX,
divOverlay.offsetTop - e.clientY
];
}, true);
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
document.addEventListener('mousemove', function(e) {
event.preventDefault();
if (isDown) {
divOverlay.style.left = (e.clientX + offset[0]) + 'px';
divOverlay.style.top = (e.clientY + offset[1]) + 'px';
}
}, true);
回答2:
Is jQuery an option for you? It makes what you are doing really simple since the code already exists.
http://jqueryui.com/demos/draggable/
Demo : http://jsfiddle.net/wfbY8/4/
JavaScript Code
window.onload = addListeners;
function addListeners(){
document.getElementById('dxy').addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
function mouseUp()
{
window.removeEventListener('mousemove', divMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove', divMove, true);
}
function divMove(e){
var div = document.getElementById('dxy');
div.style.position = 'absolute';
div.style.top = e.clientY + 'px';
div.style.left = e.clientX + 'px';
}
回答3:
I did make something similar few weeks ago for Angular, see here. It might help you a bit.
Basically, I wanted to do something you're probably thinking of doing, but to use drag events you also need to drop the elements you're dragging (at least that's what I ended up searching). So if you just want to drag/move the elements you need to be able to set their position on the page using top
, bottom
and left
, right
styles. So you those elements must have the position fixed
or absolute
ideally.
Then you go for the core of this, which is to calculate vector your going to move the element with. Because mousemove
event only dispatches the MouseEvent
which get you an access to mouse coordinates, you can count up in what vector your mouse has moved and move the element by the same vector.
Basically what I did was (hope it's understandable in ES5):
var elementPosition = [0,0];
var mousePosition = [0,0];
var element = document.getElementById('yourElement');
var mainEH = function (event) {
mousePosition = [event.clientX, event.clientY];
document.addEventListener('mousemove', calcEH);
document.addEventListener('mouseup', removeHandlers);
document.addEventListener('contextmenu', removeHandlers);
};
var calcEH = function (event) {
var vector = [-mousePosition[0] + event.clientX, -mousePosition[1] + event.clientY];
mousePosition = [mousePosition[0] + vector[0], mousePosition[1] + vector[1]];
elementPosition = [elementPosition[0] + vector[0], elementPosition[1] + vector[1]];
updatePosition();
};
var removeHandlers = function () {
document.removeEventListener('mousemove', calcEH);
document.removeEventListener('mouseup', removeHandlers);
document.removeEventListener('contextmenu', removeHandlers);
};
function updatePosition() {
element.style.left = elementPosition[0] + "px";
element.style.top = elementPosition[1] + "px";
}
element.addEventListener('mousedown', mainEH, true);
I'm not sure if this exact code is working as I cannot test it now, but you can see here how I did this using angular. Hope it'll work just fine for you. At least you get the idea. Anyway, you might need to run some function that sets up initial position of the element for you.
UPDATE
I've just realized that it's not exactly what you're looking for. If I understood you correctly you want to move the whole element while dragging and dropping. However I will probably leave the answer here because the solution might be pretty much similar. I would probably do it by using the logic I posted before and to actually be able to move the element I would set it's position to absolute while mousemove event is fired, then on mouseup you can remove position absolute attribute.
回答4:
Here is an example for drag item .
For css
, we need position: absolute
For js
, remove onmouseup
and onmousemove
event after finish drag
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.AB {
background: red;
position: absolute;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="A" class="AB"></div>
<script type="text/javascript">
var divA = document.getElementById("A");
divA.addEventListener('mousedown', function() {
startDrag();
});
function startDrag() {
document.onmouseup = finishDrag;
document.onmousemove = function(e) {
divA.style.top = (divA.offsetTop + e.movementY) + "px";
divA.style.left = (divA.offsetLeft + e.movementX) + "px";
}
}
function finishDrag() {
document.onmouseup = null;
document.onmousemove = null;
}
</script>
</body>
</html>
来源:https://stackoverflow.com/questions/45831399/javascript-use-drag-to-move-element