javascript 使用拖动来移动元素
javascript use drag to move element
如何设置元素的位置?当用户拖动一个元素(图像)时,我想让它同步移动。我看到正在调用我的 "mousemove" 处理程序。但是我无法让元素实际移动。
这是 mousemove 处理程序(被拖动的元素是 "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;
}
这是 "overlay" 的 html:
<div id="overlay">
... some other stuff ...
<img id="large" src="something.jpg" >
</div>
和 css:
#overlay {position:absolute; left:0; top:0}
似乎显示了默认的拖动操作,它是 "overlay" 随鼠标移动的影子。但是元素本身并没有移动。
jQuery 适合您吗?由于代码已经存在,它使您正在做的事情变得非常简单。
http://jqueryui.com/demos/draggable/
演示:http://jsfiddle.net/wfbY8/4/
JavaScript代码
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';
}
不确定您的实际实施情况。但是这段代码有效:
要使用您的代码来完成,这里是代码。您的代码的一个明显问题是您需要将 'px' 添加到 style.left 和 style.right。此外,您实际上如何处理代码中的事件也是未知的。使用这段代码,元素在一个圆圈中移动,你需要修复它,但你明白了。
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);
下面是另一种方法。
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);
几周前我确实为 Angular、see here 做了类似的东西。它可能会对你有所帮助。
基本上,我想做一些您可能正在考虑做的事情,但是要使用拖动事件,您还需要放下正在拖动的元素(至少这是我最终搜索的结果)。因此,如果您只想 drag/move 元素,您需要能够使用 top
、bottom
和 left
、right
样式设置它们在页面上的位置.因此,理想情况下,这些元素必须具有 fixed
或 absolute
的位置。
然后你进入这个的核心,即计算你要用来移动元素的向量。因为 mousemove
事件只派发 MouseEvent
,它可以让你访问鼠标坐标,你可以计算你的鼠标在哪个向量中移动,并通过相同的向量移动元素。
基本上我所做的是(希望它在 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);
我不确定这段代码是否有效,因为我现在无法对其进行测试,但您可以看到 here 我是如何使用 angular 完成此操作的。希望它对你有用。至少你明白了。无论如何,您可能需要 运行 一些为您设置元素初始位置的函数。
更新
我刚刚意识到这不是您要找的东西。如果我理解正确的话,你想在拖放时移动整个元素。但是我可能会在这里留下答案,因为解决方案可能非常相似。我可能会使用我之前发布的逻辑来做到这一点,并且为了真正能够移动元素,我会在触发 mousemove 事件时将它的位置设置为绝对位置,然后在 mouseup 上你可以删除位置绝对属性。
如何设置元素的位置?当用户拖动一个元素(图像)时,我想让它同步移动。我看到正在调用我的 "mousemove" 处理程序。但是我无法让元素实际移动。
这是 mousemove 处理程序(被拖动的元素是 "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;
}
这是 "overlay" 的 html:
<div id="overlay">
... some other stuff ...
<img id="large" src="something.jpg" >
</div>
和 css:
#overlay {position:absolute; left:0; top:0}
似乎显示了默认的拖动操作,它是 "overlay" 随鼠标移动的影子。但是元素本身并没有移动。
jQuery 适合您吗?由于代码已经存在,它使您正在做的事情变得非常简单。
http://jqueryui.com/demos/draggable/
演示:http://jsfiddle.net/wfbY8/4/
JavaScript代码
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';
}
不确定您的实际实施情况。但是这段代码有效:
要使用您的代码来完成,这里是代码。您的代码的一个明显问题是您需要将 'px' 添加到 style.left 和 style.right。此外,您实际上如何处理代码中的事件也是未知的。使用这段代码,元素在一个圆圈中移动,你需要修复它,但你明白了。
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);
下面是另一种方法。 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);
几周前我确实为 Angular、see here 做了类似的东西。它可能会对你有所帮助。
基本上,我想做一些您可能正在考虑做的事情,但是要使用拖动事件,您还需要放下正在拖动的元素(至少这是我最终搜索的结果)。因此,如果您只想 drag/move 元素,您需要能够使用 top
、bottom
和 left
、right
样式设置它们在页面上的位置.因此,理想情况下,这些元素必须具有 fixed
或 absolute
的位置。
然后你进入这个的核心,即计算你要用来移动元素的向量。因为 mousemove
事件只派发 MouseEvent
,它可以让你访问鼠标坐标,你可以计算你的鼠标在哪个向量中移动,并通过相同的向量移动元素。
基本上我所做的是(希望它在 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);
我不确定这段代码是否有效,因为我现在无法对其进行测试,但您可以看到 here 我是如何使用 angular 完成此操作的。希望它对你有用。至少你明白了。无论如何,您可能需要 运行 一些为您设置元素初始位置的函数。
更新
我刚刚意识到这不是您要找的东西。如果我理解正确的话,你想在拖放时移动整个元素。但是我可能会在这里留下答案,因为解决方案可能非常相似。我可能会使用我之前发布的逻辑来做到这一点,并且为了真正能够移动元素,我会在触发 mousemove 事件时将它的位置设置为绝对位置,然后在 mouseup 上你可以删除位置绝对属性。