成果展示:
    codepen链接:https://codepen.io/ashipiling/pen/wvJyaza 该网站实现了demo,可进行拖拽尝试和代码修改。
    4selectbox.gif
    图1 画板自由拖拽示例。
    拟解决问题:
    a) model builder应提供多选元素的功能,第一种方案是按住shift在选择物体,第二种则是绘制选框。第二种更加简便和直白;
    b) 如果没有选中元素,则应删除选框;
    c) 选中元素后,选框应紧紧包围所有被选中的元素,允许有间隙;
    d) 如果对选中物体没有进行操作,则删除选框(此文章不涉及该操作)。

    实现思路:
    a) 画板绑定自定义onmousedown move和up函数(替换之前绑定的拖拽画板函数);
    b) 在绘制之前,画板中的元素位置应保存下来。例如用全局变量dict保存元素四个角位置信息;
    c) onmousedown,与画板绑定;
    判断e.currentTarget的className和id是否是想要被移动的画板;
    记录鼠标点击下的位置old_xy;
    创建选框div 赋予classname 虚线边框,背景透明。画板挂载该div。
    记录全局变量为绘制选框;
    d) onmousemove,鼠标在绑定的元素内移动时高频触发;
    判断当前动作是否为绘制选框;,如果是则进行下一步;
    获取鼠标当前的位置,与old_xy一起计算选框div的宽高和left top信息;
    更新选框div的csstext达到实时绘制选框的效果。
    e) onmouseup,鼠标在绑定的元素内释放时触发一次。
    计算选框内部是否含有元素,如果没有则删除选框div。如果有则修正选框位置,并高亮元素(该文章不涉及该操作)。
    清理全局变量等。

    实现细节:**
    javascript代码
    var gselectbox_down_x = 0; //mousedown时候的坐标。
    var g_selectbox_down_y = 0;
    //mousedown时候的坐标。
    var g_current_selectbox_id = “”;
    //当前选框的id,mousedown的时候确定。
    var g_selectbox_padding = 10;
    //选中物体后,选框距离元素外围的距离。
    var g_selectbox_down_flag = “up”;
    //是否开始选框的flag,防止鼠标自由移动时频繁触发函数。
    var g_component_corner_position_dict = {“test_div”: {“left_x”: 300, “left_y”: 100, “right_x”: 450, “right_y”: 250,}, }
    //实际上是根据绘制元素时生成的,但这里为了演示,直接给定值。_

    function selectboxmouse_down(e) {
    var draw_canvas = document.getElementById(“draw_canvas”);
    g_selectbox_down_x = e.pageX;
    g_selectbox_down_y = e.pageY;
    var div = document.createElement(“div”);
    //新建选框div
    div.id = “selectbox
    “ + current(); //current函数返回当前时间戳,避免多次选框id一致
    gcurrent_selectbox_id = div.id; //全局变量保存id,方便move和up函数使用
    div.className = “selectbox”;
    //虚线外框
    draw_canvas.append(div);
    g_selectbox_down_flag = “down”;
    //开始绘制
    }
    //box mousemove函数, 更新box位置
    function selectbox_mouse_move(e) {
    if (g_selectbox_down_flag === “down”) {
    //只有flag为down的时候执行下列函数
    var relative_x = e.pageX;
    var relative_y = e.pageY;
    var div = document.getElementById(g_current_selectbox_id);
    var res_dict = calc_selectbox_whlt(relative_x, relative_y);
    //根据保存的xy和当前xy计算框的长宽和left top值
    var csstext = combine_csstext(res_dict);
    //将计算出来的数值转换为csstext格式
    div.style.cssText = csstext;
    //csstext赋值
    }
    }
    //box mouseup函数, 修正位置,重绘box
    function selectbox_mouse_up(e) {
    var div = document.getElementById(g_current_selectbox_id);
    var relative_x = e.pageX;
    var relative_y = e.pageY;
    var res_dict = calc_selectbox_whlt(relative_x, relative_y);
    //鼠标放开时最后计算一次宽高和left top
    var selected_info = calc_which_box_selected(res_dict);
    //将选框位置信息和元素的位置信息进行比较,判断是否有元素在选框内部_

    1. if (selected_info["id"].length === 0) { _//如果没有选中元素则删除选框_<br /> removeElement(div);<br /> } else {<br /> modify_selectbox_postion(selected_info["position"]); _//如果有选中元素则进行选框的位置的微调,变成紧紧围绕元素的选框_<br /> }<br /> g_selectbox_down_x = 0; _//清除全局变量_<br /> g_selectbox_down_y = 0;<br /> g_selectbox_down_flag = "up";<br />}