我试图制作它,以便当用户按住鼠标按钮然后拖动鼠标时会移动一堆元素。我试图通过听mousedown和mousemove事件并比较它们的位置来做到这一点。位置的差异用于计算移动所有元素的距离。目标是感觉所有元素都被拖动了。但是出于某种原因,我的方法会导致元素飞到各处。
以下是我尝试做的一个例子:
window.onload = function(){
var mouse = {isDown : false, lastX : null, lastY : null };
document.body.addEventListener("click", function(event){
var el = document.createElement("div");
el.className = "box";
el.style.left = event.clientX + "px";
el.style.top = event.clientY + "px";
el.style.backgroundColor = "BLACK";
el.style.width = "16px";
el.style.height = "16px";
el.style.position = "absolute";
document.body.appendChild(el);
});
document.body.addEventListener("mousedown", function(event){
mouse.isDown = true;
mouse.lastX = event.clientX;
mouse.lastY = event.clientY;
});
document.body.addEventListener("mouseup", function(){
mouse.isDown = false;
mouse.lastX = null;
mouse.lastY = null;
});
var removePx = function(string){return string.substring(0, string.length -2);}
document.body.addEventListener("mousemove", function(event){
console.log("move (" + event.clientX + "," + event.clientY + ")");
if(mouse.isDown){
var deltaX = event.clientX - mouse.lastX;
var deltaY = event.clientY - mouse.lastY;
console.log("DeltaX " + deltaX);
console.log("DeltaY " + deltaY);
var boxes = document.getElementsByClassName("box");
for(var i = 0; i<boxes.length; i++){
var box = boxes[i];
box.style.left = removePx(box.style.left) + deltaX + "px";
box.style.top = removePx(box.style.top) + deltaY + "px";
}
mouse.lastX = event.clientX;
mouse.lastY = event.clientY;
}
});
}
这里出了什么问题?还有,有更好的方法来实现这一目标吗?
答案 0 :(得分:1)
关于您的代码,我会说transform
对于此类事物(而不是左/上)的定位更受欢迎 - 请参阅讨论http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/。
无论如何,我没有仔细查看你的代码,而是自己尝试了解我所理解的内容。我只使用了一个关于拖放的简单模式:
这是一个片段:
var main = document.querySelector('main');
var movable = [].slice.call(document.querySelectorAll('.movable'));
var _state = {
x: 0,
y: 0,
matrix: [1, 0, 0, 1, 0, 0],
moving: false
};
movable.forEach(function (elem) {
elem.style.transform = 'matrix(' + _state.matrix.join(',') + ')'
});
function onMouseDown (e) {
_state.moving = true;
_state.x = e.clientX;
_state.y = e.clientY;
_state.matrix = matrixToArray(e.target.style.transform);
}
function matrixToArray (matrix) {
return matrix
.match(/matrix\((.*)\)/)[1]
.split(' ')
.join('')
.split(',')
.map(function (a) {
return +a;
});
}
function onMouseMove (e) {
if (!_state.moving)
return;
var dx = e.clientX - _state.x;
var dy = e.clientY - _state.y;
_state.matrix[4] += dx;
_state.matrix[5] += dy;
var transf = 'matrix(' + _state.matrix.join(',') + ')'
movable.forEach(function (elem) {
elem.style.transform = transf;
});
_state.x = e.clientX;
_state.y = e.clientY;
}
function onMouseUp (e) {
_state.moving = false;
_state.x = e.clientX;
_state.y = e.clientY;
}
main.addEventListener('mousemove', onMouseMove);
main.addEventListener('mouseup', onMouseUp);
movable.forEach(function (elem) {
elem.addEventListener('mousedown', onMouseDown);
});
html,
body,
main {
width: 100%;
height: 100%;
}
div {
width: 50px;
height: 50px;
position: absolute;
}
#d1 { background: black; left: 10px; top: 10px;}
#d2 { background: brown; left: 70px; top: 10px;}
#d3 { background: green; left: 10px; top: 70px ;}
#d4 { background: purple; left: 70px; top: 70px ;}
<main>
<div id="d1" class="movable"></div>
<div id="d2" class="movable"></div>
<div id="d3" class="not-movable"></div>
<div id="d4" class="movable"></div>
</main>
ps:这不是那么有效率。人们可以肯定地重复这个并创建一个更好的版本!