成果展示:

codepen链接:https://codepen.io/ashipiling/pen/poedxQV 该网站实现了demo,可进行拖拽尝试和代码修改。
2move.gif
图1 元素自由移动的演示。

拟解决需求:

1)点击右侧元素并移动,元素跟随鼠标自由移动;

实现思路:
a)绘制元素时立即绑定onmousedown函数,使用e.currentTarget精准获取元素,(currentTarget表示被绑定的元素。如果使用e.target则会获取鼠标点击的最上层物体,很可能是元素内部的一个输入框。这不是我们想要改变位置的物体)
b)右侧页面(画板)绑定onmousemove和onmouseup函数。(不能将mousemove绑定在元素上,因为函数仅在元素所在位置起作用,鼠标移动速度超过刷新率则会出现问题)
c)onmousedown,鼠标在绑定的元素按下时触发一次;
1) 判断e.currentTarget的className和id是否是想要被移动的元素(通常是对的)
2)保存元素id为全局变量
d)onmousemove,鼠标在绑定的元素内移动时高频触发;
1)通过全局变量中的id获取当前要移动的元素;
1)获取鼠标当前的绝对位置,转换为右侧页面的相对位置;
2)元素的left和top设置为鼠标新的相对位置位置,进行移动。
e)onmouseup,鼠标在绑定的元素内释放时触发一次。
1)获取鼠标当前的绝对位置,保存元素位置,清理全局变量等;

实现细节:
HTML代码




javascript代码
//全局变量
var g_left_sidebar_width = 210; //sidebar的宽度,sidebar关闭后这个值变为0
var g_top_bar_height = 70; //顶栏高度70px
var g_move_comp_x_old = 0;
var g_move_comp_y_old = 0;
var g_move_component_id = “”;

function component_mouse_down(e) {
var component = e.currentTarget; //获取mousedown函数绑定的元素
g_move_component_id = component.id; //将该元素的id设置为全局变量,方便move函数使用
g_move_comp_x_old = e.pageX - g_left_sidebar_width; //记录当前位置
g_move_comp_y_old = e.pageY - g_top_bar_height;
}
**
function mover_mouse_move(e) {
e.preventDefault();
var relativeX = e.pageX - g_left_sidebar_width; //计算鼠标当前相对位置
var relativeY = e.pageY - g_top_bar_height;
var component = document.getElementById(g_move_component_id); //获取要被移动的元素
var name = component.className.split(“ “)[2];
var move_x = relativeX - g_move_comp_x_old; //计算鼠标偏移量,为什么使用偏移量而不是直接对元素的left赋值,是由于后续元素通过scale放大后,直接赋值会有bug。
var move_y = relativeY - g_move_comp_y_old;
g_move_comp_x_old = relativeX; //更改全局变量为新的位置
g_move_comp_y_old = relativeY;
change_site(component, name, move_x, move_y); //调用更改元素位置的函数
}

function mover_mouse_up(e) {
g_move_comp_x_old = 0; //清理全局变量
g_move_comp_y_old = 0;
g_move_component_id = “”;
}

function change_site(div, name, moveX, moveY) {
var csstext = div.style.cssText;
var tmp_list = csstext.split(“;”);
var left = Number(tmp_list[2].split(“:”)[1].replace(/px/g, “”)); //获取元素原本的left和top
var top = Number(tmp_list[3].split(“:”)[1].replace(/px/g, “”));
var new_left = left + moveX; //计算新的left
var new_top = top + moveY;
csstext = “width: “ + 200+ “px;” + “height: “ + 200 + “px;” + “left: “ + new_left + “px;” + “top: “ + new_top + “px;”;
div.style.cssText = csstext; //cssText赋值
}