真正的原生js写的拖拽来了

来源:互联网 发布:微软雅黑bold for mac 编辑:程序博客网 时间:2024/06/06 11:02

前几次的拖拽都是基于HTML5的拖拽API写的,在项目中我发现我自己写的只支持谷歌浏览器,火狐和IE都不支持,这就很尴尬了,当时的我内心是崩溃的。。。不过思路是有了,还是原来的思路,但是就是拖拽的时候不好弄,我也试着引用基于jquery的插件,但是不行,老是冲突,我在这里的意思不是说HTML5的拖拽API兼容性不好,应该是我自己的代码有问题,我真的是,一股傲气冲上头顶,老子要写纯原生的,于是我就上网查找资料,用mousedown、mousemove、mouseup事件配合来进行拖拽,基于以前拖拽的思路,做出了流程图,比1.0版本还要好,拖动起来还要唯美,还要舒服,下面上2.0版本的代码

<!DOCTYPE html><html lang="en" onselectstart='return false'><head>    <meta charset="UTF-8">    <title>Document</title>    <style type="text/css">        #d1{            width: 800px;            height:800px;            border:1px solid #ccc;            background: #fafafa;            position: relative;        }        #d1 .drawContent div{            width:130px;            height:30px;            border: 1px solid #ccc;            background: #fff;            border-radius: 8px;            position: absolute;            text-align: center;            line-height: 30px;            z-index: 2;            cursor:move;        }        #d1 .drawContent div span{            display: inline-block;            width: 130px;            height: 20px;            line-height: 20px;            cursor: move;        }        #d1 .drawContent div i{            display: inline-block;            width: 10px;            height:10px;            background: #fff;            border-radius: 50%;            position: absolute;            top:-7px;            left:46%;            border:1px solid #ccc;            cursor: default;        }        #d1 .drawContent div s{            display: inline-block;            width: 10px;            height:10px;            background: #fff;            border-radius: 50%;            position: absolute;            bottom:-7px;            left:46%;            border:1px solid #ccc;            cursor: crosshair;        }        #d1 .drawContent div u{            position: absolute;            display: inline-block;            border:6px solid transparent;            border-top:6px solid #ccc;            top:0px;            left:58px;        }        #d1 .drawContent div s:hover{            background: #F8BC06;        }        #d1 svg{            width: 100%;            height:100%;            position: absolute;            z-index: 1;        }        #d2{            width: 300px;            height:2000px;        }        ul li{            cursor: default;        }    </style></head><body>    <ul>        <li data-name = 'xiangjiao'>            <span>香蕉</span>        </li>        <li data-name = 'pingguo'>            <span>苹果</span>        </li>        <li data-name = 'liulian'>            <span>榴莲</span>        </li>        <li data-name = 'xigua'>            <span>西瓜</span>        </li>        <li data-name = 'xihongshi'>            <span>西红柿</span>        </li>    </ul>    <div id = 'd1'>        <div class = "drawContent">        </div>        <svg></svg>    </div>    <div id = 'd2'></div>    <script type="text/x-handlebars-template" id = "content">        {{#each this}}            <div class = "{{name}}" data-id = '{{id}}' data-inx = '{{inx}}' data-iny = '{{iny}}'style = "top:{{y}}px;left:{{x}}px">                <i title = "输入" style = "display:{{circle}}"></i>                <u style = "display:{{arrow}}"></u>                <span class = "label">{{label}}</span>                <s title = "输出"></s>            </div>            <ul class = "clickMenu" style = "top:{{mTop}}px;left:{{mLeft}}px;display:{{menuShow}}">                <li>重命名</li>                <li class = "delete">删除</li>                <li>全部运行</li>                <li>运行到此处</li>                <li>运行该节点</li>                <li>从此节点运行</li>                <li>查看数据</li>                <li>查看日志</li>            </ul>        {{/each}}    </script>    <script type="text/x-handlebars-template" id = "line">        {{#each this}}            {{#each link}}                <g class = "{{name}}">                    <path d = "M{{../outx}} {{../outy}} Q{{mx1}} {{my1}} {{mx2}} {{my2}} T{{dx}} {{dy}}" stroke = "#CCCCCC" fill = "none" style = "stroke-width: 1px;"/>                </g>            {{/each}}        {{/each}}    </script>    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>    <script type="text/javascript" src = 'js/handlebars-v4.0.10 .js'></script>    <script type="text/javascript">        var element;        // 获得容器的宽度        var dWidth = Number($('#d1').css('width').slice(0,-2));        // 获得容器的高度        var dHeight = Number($('#d1').css('height').slice(0,-2));        var dragData = [            {                id:0,                name:'xiangjiao',                label:'香蕉',                draw:false,                link:[],                linked:[],                outx:268,                outy:430,                dx:0,                dy:0,                inx:265,                iny:399,                x:200,                y:400,                arrow:"none",                circle:"inline-block",            },{                id:1,                name:'pingguo',                draw:false,                label:'苹果',                link:[],                linked:[],                outx:468,                outy:230,                dx:0,                dy:0,                inx:465,                iny:199,                x:400,                y:200,                arrow:"none",                circle:"inline-block",            },        ]        function reload(){            var myTemplate = Handlebars.compile($("#content").html());            $('#d1 .drawContent').html(myTemplate(dragData));            var myLine = Handlebars.compile($("#line").html());            $('#d1 svg').html(myLine(dragData));        }        reload();        //按下列表创建虚像        $('ul li ').mousedown(function(e){            var span = document.createElement('span');            span.innerHTML = $(this).text();            span.setAttribute('data-name',$(this).data('name'));            span.style.opacity = 0.6;            span.style.position = 'absolute';            span.style.top = (e.pageY-8) + 'px';            span.style.left = (e.pageX-8) + 'px';            span.style.zIndex = 5;            $(this).append(span);            element = $(this).children('span:last-child');            console.log('element',element);        })        // 文档鼠标抬起时判断在不在容器内,创建元素        $(document).mouseup(function(e){            console.log('e.target',e.target);            $('#d1').unbind('mousemove');            if(element){                if(e.pageY > $('#d1').offset().top && e.pageX > $('#d1').offset().left){                    console.log('e.offsetY',e.offsetY,'e.offsetX',e.offsetX);                    console.log(element);                    var x = e.pageX - $('#d1').offset().left - e.offsetX;                    var y = e.pageY - $('#d1').offset().top - e.offsetY;                    //判断x                    if((x >= 0 && x <= dWidth - 132)){                        x = x;                    }else if(x < 0){                        x = 1;                    }else if(x > dWidth - 132){                        x = dWidth - 132                    }                    //判断y                    if((y >= 0 && y <= dHeight - 32)){                        y = y;                    }else if(y < 0){                        y = 1;                    }else if(y > dHeight - 32){                        y = dHeight - 32                    }                    dragData.push({                        id:dragData.length,                        name:element.data('name'),                        draw:false,                        label:element.text(),                        x:x,                        y:y,                        outx:x + 68,                        outy:y + 30,                        inx:x +65,                        iny:y - 1,                        link:[],                        linked:[],                        dx:0,                        dy:0,                        arrow:"none",                        circle:"inline-block"                    })                    reload();                    element.remove();                    element = undefined;                }else{                    element.remove();                    element = undefined;                }            }        })        //拖动虚像在文档中进行移动        $(document).mousemove(function(e){            //console.log('x',e.pageX,'y',e.pageY);            if(element){                element.css({'top':(e.pageY - 8) + 'px','left':(e.pageX - 8)});            }        })        //给创建的新的组件加上mousedown事件        var waitElement;        $('#d1 > .drawContent').on('mousedown','div',function(e){            waitElement = $(this);            console.log(waitElement);            var dx = e.offsetX            var dy = e.offsetY            console.log('e.offsetX',e.offsetX)            console.log('e.offsetY',e.offsetY)            //容器的mousemove事件            $('#d1').mousemove(function(e){                if(waitElement){                    waitElement.css({top:(e.pageY - $('#d1').offset().top - dy) + 'px',left:(e.pageX - $('#d1').offset().left - dx) + 'px'});                    console.log(waitElement.data('id'));                    var id = waitElement.data('id')                    var x = e.pageX - $('#d1').offset().left - dx;                    var y = e.pageY - $('#d1').offset().top - dy;                    //判断x                    if((x >= 0 && x <= dWidth - 132)){                        x = x;                    }else if(x < 0){                        x = 1;                    }else if(x > dWidth - 132){                        x = dWidth - 132                    }                    //判断y                    if((y >= 0 && y <= dHeight - 32)){                        y = y;                    }else if(y < 0){                        y = 1;                    }else if(y > dHeight - 32){                        y = dHeight - 32                    }                    for(var i = 0; i < dragData.length; i++){                        if(id == dragData[i].id){                            console.log(dragData[i]);                            dragData[i].x = x;                            dragData[i].outx = dragData[i].x + 68;                            dragData[i].inx = dragData[i].x + 65;                            dragData[i].y = y;                            dragData[i].outy = dragData[i].y + 30;                            dragData[i].iny = dragData[i].y - 1;                            console.log('要开始了')                            for(let j = 0; j < dragData[i].link.length;j++){                                dragData[i].link[j].linkId = parseFloat(dragData[i].link[j].name.split("|")[1]);                            }                            for(var k = 0 ; k < dragData[i].linked.length;k++){                                console.log('dragData[i].linked[k]',dragData[i].linked[k]);                                for(let j = 0; j < dragData.length;j++){                                    if(dragData[i].linked[k].linkedNum == dragData[j].id){                                        console.log('ID一样了啊');                                        for(let m = 0; m < dragData[j].link.length; m++){                                            if(dragData[i].linked[k].name == dragData[j].link[m].name){                                                console.log("名字一样了啊");                                                dragData[j].link[m].dx = dragData[i].inx;                                                dragData[j].link[m].dy = dragData[i].iny;                                                dragData[j].link[m].mx1 = dragData[j].outx;                                                dragData[j].link[m].my1 = dragData[j].link[m].dy > dragData[j].outy?dragData[j].outy + (dragData[j].link[m].dy-dragData[j].outy)/4:dragData[j].outy - (dragData[j].link[m].dy-dragData[j].outy)/4;                                                dragData[j].link[m].mx2 = dragData[j].outx + (dragData[j].link[m].dx-dragData[j].outx)/2,                                                dragData[j].link[m].my2 = dragData[j].outy +(dragData[j].link[m].dy-dragData[j].outy)/2                                            }                                        }                                    }                                }                            }                            reload();                            if(dragData[i].link.length > 0){                                for(var j = 0; j < dragData[i].link.length;j++){                                    dragData[i].link[j].mx1 = dragData[i].outx;                                    dragData[i].link[j].my1 = dragData[i].link[j].dy > dragData[i].outy?dragData[i].outy + (dragData[i].link[j].dy-dragData[i].outy)/4:dragData[i].outy - (dragData[i].link[j].dy-dragData[i].outy)/4;                                    dragData[i].link[j].mx2 = dragData[i].outx + (dragData[i].link[j].dx-dragData[i].outx)/2,                                    dragData[i].link[j].my2 = dragData[i].outy +(dragData[i].link[j].dy-dragData[i].outy)/2                                }                            }                            reload();                        }                    }                    console.log(dragData);                    reload();                }            })        })        //给创建的新的组件加上mouseup事件        $('#d1 > .drawContent > div').mouseup(function(){            waitElement = undefined;            console.log(waitElement);        })        //容器的mouseup事件        $('#d1').mouseup(function(e){            console.log('我抬起了');            waitElement = undefined;            $('#d1').unbind('mousemove');            if(waitElement){                waitElement.css({top:e.pageY - $('#d1').offset().top,left:e.pageX - $('#d1').offset().left})            }        })        //给组件的输出圆圈加入mouseenter事件使组件不能拖拽        $('#d1 > .drawContent').on('mouseenter','div>s',function(){            console.log('进入了输出');            waitElement = undefined;            $('#d1').unbind('mousemove');            $('svg').unbind('mousemove');            $('#d1 > .drawContent').off('mousedown','div');        })        //先给组件的输出源加入mousedown事件,先创建连线        $('#d1 > .drawContent').on('mousedown','div>s',function(){            //先创建连线的数据            console.log($(this).parent());            var parent = $(this).parent();            var id = parent.data('id');            console.log('idididid',id);            for(var i = 0; i < dragData.length; i++){                if(dragData[i].id == id){                    dragData[i].draw = true;                    dragData[i].link.push({                        name:id + parent.attr('class'),                        dx:0,                        dy:0,                        mx1:0,                        my1:0,                        mx2:0,                        my2:0                    });                    console.log('dragData哈哈哈哈',dragData);                    $('body').on('mouseup',function(e){                        for(var j = 0; j < dragData.length; j++){                            if(id == dragData[j].id){                                console.log('页面抬起了');                                dragData[j].draw = false;                                if(e.target.title){                                    if(e.target.title == "输入"){                                        $('svg').unbind('mousemove');                                        dragData[j].link[dragData[j].link.length - 1].name = dragData[j].link[dragData[j].link.length - 1].name + "|" + e.target.parentNode.dataset.id + e.target.parentNode.className;                                        dragData[j].link[dragData[j].link.length - 1].dx = Number(e.target.parentNode.dataset.inx);                                        dragData[j].link[dragData[j].link.length - 1].dy = Number(e.target.parentNode.dataset.iny);                                        for(let i = 0; i < dragData.length; i++){                                            if(e.target.parentNode.dataset.id == dragData[i].id){                                                dragData[i].linked.push({                                                    name: dragData[j].link[dragData[j].link.length - 1].name,                                                    linkedNum:parseFloat(dragData[j].link[dragData[j].link.length - 1].name)                                                })                                                dragData[i].circle = "none";                                                dragData[i].arrow = "inline-block";                                            }                                        }                                    }else{                                        dragData[j].link.splice(dragData[j].link.length-1,1);                                        $('svg').unbind('mousemove');                                        reload();                                    }                                }else{                                    dragData[j].link.splice(dragData[j].link.length-1,1);                                    $('svg').unbind('mousemove');                                }                                reload();                            }                        }                        $('body').unbind('mouseup');                    })                }            }        })        //给输出圆圈添加mouseup事件        $('#d1 > .drawContent').on('mouseup','div>s',function(){            var parent = $(this).parent();            for(var i = 0; i < dragData.length;i++){                if(parent.data('id') == dragData[i].id){                    dragData[i].draw = false;                    console.log(dragData[i]);                }            }        })        //给组件的输出源加入mouseleave事件使组件继续能够拖拽        $('#d1 > .drawContent').on('mouseleave','div>s',function(){            console.log('离开了了输出');            console.log($(this).parent());            waitElement = $(this).parent();            var id = waitElement.data('id')            //重新赋值使选中组件能够进行拖拽            $('#d1 > .drawContent').on('mousedown','div',function(e){                waitElement = $(this);                console.log(waitElement);                var dx = e.offsetX                var dy = e.offsetY                console.log('e.offsetX',e.offsetX)                console.log('e.offsetY',e.offsetY)                //容器的mousemove事件                $('#d1').mousemove(function(e){                    if(waitElement){                        waitElement.css({top:(e.pageY - $('#d1').offset().top - dy) + 'px',left:(e.pageX - $('#d1').offset().left - dx) + 'px'});                        console.log(waitElement.data('id'));                        var id = waitElement.data('id')                        var x = e.pageX - $('#d1').offset().left - dx;                        var y = e.pageY - $('#d1').offset().top - dy;                        //判断x                        if((x >= 0 && x <= dWidth - 132)){                            x = x;                        }else if(x < 0){                            x = 1;                        }else if(x > dWidth - 132){                            x = dWidth - 132                        }                        //判断y                        if((y >= 0 && y <= dHeight - 32)){                            y = y;                        }else if(y < 0){                            y = 1;                        }else if(y > dHeight - 32){                            y = dHeight - 32                        }                        for(var i = 0; i < dragData.length; i++){                            if(id == dragData[i].id){                                console.log(dragData[i]);                                dragData[i].x = x;                                dragData[i].outx = dragData[i].x + 68;                                dragData[i].inx = dragData[i].x + 65;                                dragData[i].y = y;                                dragData[i].outy = dragData[i].y + 30;                                dragData[i].iny = dragData[i].y - 1;                                console.log('要开始了')                                for(let j = 0; j < dragData[i].link.length;j++){                                    dragData[i].link[j].linkId = parseFloat(dragData[i].link[j].name.split("|")[1]);                                }                                for(var k = 0 ; k < dragData[i].linked.length;k++){                                    console.log('dragData[i].linked[k]',dragData[i].linked[k]);                                    for(let j = 0; j < dragData.length;j++){                                        if(dragData[i].linked[k].linkedNum == dragData[j].id){                                            console.log('ID一样了啊');                                            for(let m = 0; m < dragData[j].link.length; m++){                                                if(dragData[i].linked[k].name == dragData[j].link[m].name){                                                    console.log("名字一样了啊");                                                    dragData[j].link[m].dx = dragData[i].inx;                                                    dragData[j].link[m].dy = dragData[i].iny;                                                    dragData[j].link[m].mx1 = dragData[j].outx;                                                    dragData[j].link[m].my1 = dragData[j].link[m].dy > dragData[j].outy?dragData[j].outy + (dragData[j].link[m].dy-dragData[j].outy)/4:dragData[j].outy - (dragData[j].link[m].dy-dragData[j].outy)/4;                                                    dragData[j].link[m].mx2 = dragData[j].outx + (dragData[j].link[m].dx-dragData[j].outx)/2,                                                    dragData[j].link[m].my2 = dragData[j].outy +(dragData[j].link[m].dy-dragData[j].outy)/2                                                }                                            }                                        }                                    }                                }                                reload();                                if(dragData[i].link.length > 0){                                    for(var j = 0; j < dragData[i].link.length;j++){                                        dragData[i].link[j].mx1 = dragData[i].outx;                                        dragData[i].link[j].my1 = dragData[i].link[j].dy > dragData[i].outy?dragData[i].outy + (dragData[i].link[j].dy-dragData[i].outy)/4:dragData[i].outy - (dragData[i].link[j].dy-dragData[i].outy)/4;                                        dragData[i].link[j].mx2 = dragData[i].outx + (dragData[i].link[j].dx-dragData[i].outx)/2,                                        dragData[i].link[j].my2 = dragData[i].outy +(dragData[i].link[j].dy-dragData[i].outy)/2                                    }                                }                                reload();                            }                        }                        console.log(dragData);                        reload();                    }                })            })            //给svg加mousemove事件            for(var i = 0; i < dragData.length;i++){                if(id == dragData[i].id){                    if(dragData[i].draw == true){                        $('svg').mousemove(function(e){                            for(var i = 0; i < dragData.length;i++){                                if(id == dragData[i].id){                                    console.log(dragData[i]);                                    if(dragData[i].link[dragData[i].link.length-1]){                                        dragData[i].link[dragData[i].link.length-1].dx = e.offsetX;                                        dragData[i].link[dragData[i].link.length-1].dy = e.offsetY;                                        dragData[i].link[dragData[i].link.length-1].mx1 = dragData[i].outx;                                        dragData[i].link[dragData[i].link.length-1].my1 = dragData[i].dy > dragData[i].outy?dragData[i].outy + (dragData[i].dy-dragData[i].outy)/4:dragData[i].outy - (dragData[i].dy-dragData[i].outy)/4;                                        dragData[i].link[dragData[i].link.length-1].mx2 = dragData[i].outx + (dragData[i].dx-dragData[i].outx)/2,                                        dragData[i].link[dragData[i].link.length-1].my2 = dragData[i].outy +(dragData[i].dy-dragData[i].outy)/2                                    }                                    //////////////////////////////////////////////                                    dragData[i].dx = e.offsetX;                                    dragData[i].dy = e.offsetY;                                    dragData[i].mx1 = dragData[i].outx;                                    if(dragData[i].dy > dragData[i].outy){                                        dragData[i].my1 = dragData[i].outy + (dragData[i].dy-dragData[i].outy)/4;                                    }else{                                        dragData[i].my1 = dragData[i].outy - (dragData[i].dy-dragData[i].outy)/4;                                    }                                    dragData[i].mx2 = dragData[i].outx + (dragData[i].dx-dragData[i].outx)/2                                    dragData[i].my2 = dragData[i].outy +(dragData[i].dy-dragData[i].outy)/2                                }                            }                            reload();                            console.log(2333);                        })                    }else{                        $('svg').unbind('mousemove');                    }                }            }        })        //给svg添加mouseup事件        $('svg').mouseup(function(e){            console.log(e.target);            $('svg').unbind('mousemove');            for(var i = 0; i < dragData.length;i++){                dragData[i].draw = false;            }            console.log('起来了');        })    </script></body></html>

这里要提一嘴,因为没有用到angular,用了一套基于jquery的一个模版插件,可以对数据进行双向数据绑定,叫Handlebars.js,下面有教程链接,是一个大神的博客,冒昧的引用一下他的链接

http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html

我的主要思路还是先操作数组对象,然后再利用这个js模版引擎画到DOM中去,来两张效果图

这里写图片描述

这里写图片描述

当然我这里只是写的一个demo,具体应用到项目中去,还要根据相对定位的父元素来计算出鼠标的实际坐标,我这里默认的相对定位的父元素是body,不过我已经应用到项目中去了,肯定没问题的,ok,今天就到这里吧,终于拖拽可以消停了,哈哈哈哈哈哈!!!!!