原生javascript实现DIV拖拽并计算重复面积


Posted in Javascript onJanuary 02, 2015
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

<title>Table</title>

</head>

<style type="text/css">

body{margin:0px; padding:0px; font-size:12px}

.div{height:160px;width:160px;position:absolute; text-align:center; }

.demo1{ border:1px solid #96C2F1;background-color:#EFF7FF;left:150px;top:20px}

.demo2{ border:1px solid #9BDF70;background-color:#F0FBEB;left:450px;top:20px}

.demo3{ border:1px solid #BBE1F1;background-color:#EEFAFF;left:750px;top:20px}

.demo4{ border:1px solid #96C2F1;background-color:#EEFAFF;left:150px;top:220px}

.demo5{ border:1px solid #FFCC00;background-color:#FFFFF7;left:450px;top:220px}

.demo6{ border:1px solid #E3E197;background-color:#FFFFDD;left:750px;top:220px}

.demo7{ border:1px solid #ADCD3C;background-color:#F2FDDB;left:150px;top:420px}

.demo8{ border:1px solid #F8B3D0;background-color:#FFF5FA;left:450px;top:420px}

.demo9{ border:1px solid #D3D3D3;background-color:#F7F7F7;left:750px;top:420px}

.focus{background-color: #990000;}

</style>

<body >

<div id='demo1' class='div demo1'>demo1</div>

<div id='demo2' class='div demo2'>demo2</div>

<div id='demo3' class='div demo3'>demo3</div>

<div id='demo4' class='div demo4'>demo4</div>

<div id='demo5' class='div demo5'>demo5</div>

<div id='demo6' class='div demo6'>demo6</div>

<div id='demo7' class='div demo7'>demo7</div>

<div id='demo8' class='div demo8'>demo8</div>

<div id='demo9' class='div demo9'>demo9</div>

<script language="javascript">

(function(window,undefined){

window.Sys = function (ua){

    var b = {

        ie: /msie/.test(ua) && !/opera/.test(ua),

        opera: /opera/.test(ua),

        safari: /webkit/.test(ua) && !/chrome/.test(ua),

        firefox: /firefox/.test(ua),

        chrome: /chrome/.test(ua)

    },vMark = "";

    for (var i in b) {

        if (b[i]) { vMark = "safari" == i ? "version" : i; break; }

    }

    b.version = vMark && RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0";

    b.ie6 = b.ie && parseInt(b.version, 10) == 6;

    b.ie7 = b.ie && parseInt(b.version, 10) == 7;

    b.ie8 = b.ie && parseInt(b.version, 10) == 8;   

    return b;

}(window.navigator.userAgent.toLowerCase());
window.Sys.ie6&&document.execCommand("BackgroundImageCache", false, true);
window.$ = function(Id){

    return document.getElementById(Id);

};

window.addListener = function(element,e,fn){

    !element.events&&(element.events = {});

    element.events[e]&&(element.events[e][addListener.guid++]=fn)||(element.events[e] = {'0':fn});

    element.addEventListener?element.addEventListener(e,fn,false):element.attachEvent("on" + e,fn);

};

window.addListener.guid = 1;

window.removeListener = function(element,e,fn){

    var handlers = element.events[e],type;

    if(fn){

        for(type in handlers)

            if(handlers[type]===fn){

                element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" + e,fn);

                delete handlers[type];

            }

    }else{

        for(type in handlers){

            element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" + e,handlers[type]);

            delete handlers[type];

        }

    }        

};

window.setStyle = function(e,o){

    if(typeof o=="string")

        e.style.cssText=o;

    else    

        for(var i in o)

            e.style[i] = o[i];

};
var slice = Array.prototype.slice; 

window.Bind = function(object, fun) {

    var args = slice.call(arguments).slice(2);

    return function() {

            return fun.apply(object, args);

    };

};

window.BindAsEventListener = function(object, fun,args) {

    var args = slice.call(arguments).slice(2);

    return function(event) {

        return fun.apply(object, [event || window.event].concat(args));

    }

};

//copy from jQ

window.extend = function(){

    var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;

    if ( typeof target === "boolean" ) {

        deep = target;

        target = arguments[1] || {};

        i = 2;

    }

    if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")

        target = {};

    for(;i<length;i++){

        if ( (options = arguments[ i ]) != null )

            for(var name in options){

                var src = target[ name ], copy = options[ name ];

                if ( target === copy )

                    continue;

                if ( deep && copy && typeof copy === "object" && !copy.nodeType ){

                    target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );

                }    

                else if(copy !== undefined)

                    target[ name ] = copy;                        

            }

    }

    return target;            

};

//copy from jQ

window.each =  function ( object, callback, args ) {   

    var name, i = 0, length = object.length;   

    if ( args ) {

  args = Array.prototype.slice.call(arguments).slice(2);

        if ( length === undefined ) {   

            for ( name in object )   

                if ( callback.apply( object[ name ],[name,object[ name ]].concat(args) ) === false )   

                    break;   

        } else  

            for ( ; i < length; i++)   

                if ( callback.apply( object[ i ],[i,object[ i ]].concat(args)) === false )   //

                    break;   

    } else {      

        if ( length === undefined ) {   

            for ( name in object )   

                if ( callback.call( object[ name ], name, object[ name ] ) === false )   

                    break;   

        } else  

            for ( var value = object[0];   

                i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}   

    }   

    return object;   

};   

window.currentStyle = function(element){

    return element.currentStyle || document.defaultView.getComputedStyle(element, null);

};

window.objPos = function(elem){

    var left = 0, top = 0, right = 0, bottom = 0,doc = elem ? elem.ownerDocument : document;

    if ( !elem.getBoundingClientRect || window.Sys.ie8 ) {

        var n = elem;

        while (n) { left += n.offsetLeft, top += n.offsetTop; n = n.offsetParent; };

        right = left + elem.offsetWidth; bottom = top + elem.offsetHeight;

    } else {

        var rect = elem.getBoundingClientRect();

        left = right = doc.documentElement.scrollLeft || doc.body.scrollLeft;

        top = bottom = doc.documentElement.scrollLeft || doc.body.scrollLeft;

        left += rect.left; right += rect.right;

        top += rect.top; bottom += rect.bottom;

    }

    return { "left": left, "top": top, "right": right, "bottom": bottom };        

};

window.hasClass = function(element, className){

    return element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));

};

window.addClass = function(element, className){

    !window.hasClass(element, className)&&(element.className += " "+className);

};

window.removeClass = function(element, className){

    window.hasClass(element, className)&&(element.className = element.className.replace(new RegExp('(\\s|^)'+className+'(\\s|$)'),' '));

}

})(window);
var Drag = {

    elem    : null,

    zindex  : 0,

    options : {},

    init    : function(){        

  each(arguments,function(i,elem,oThis){

    addListener(elem,'mousedown',BindAsEventListener(oThis,oThis.start,elem));

  },this);

    },

    start : function(e,elem){

        var elem=this.elem = elem;

        elem.style.zIndex=++this.zindex;

        this.x = e.clientX - elem.offsetLeft ;

        this.y = e.clientY - elem.offsetTop;

        this.marginLeft = parseInt(currentStyle(elem).marginLeft)||0;

        this.marginTop  = parseInt(currentStyle(elem).marginTop)||0;

        Sys.ie?elem.setCapture():e.preventDefault();

        addListener(document,"mousemove",BindAsEventListener(this,this.move));

        addListener(document,"mouseup",Bind(this,this.up));  

  this.options.callbackmove&&this.options.callbackmove(this.elem);

    },

    move  : function(e){

        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

        var iLeft = e.clientX - this.x,iTop = e.clientY - this.y;obj = this.elem;

        obj.style.left = iLeft - this.marginLeft + "px";

        obj.style.top  = iTop - this.marginTop + "px";

        this.options.callbackmove&&this.options.callbackmove(this.elem);

    },

    up   : function(){

        removeListener(document,'mousemove');

        removeListener(document,'mouseup');

        Sys.ie&&this.elem.releaseCapture();

        this.options.callbackup&&this.options.callbackup(this.elem);

    }

};
var overlap = {

    hostel :{},                //所有需要计算重合的元素

    overlapList :{},           //已经重合的元素

    init : function(elems){

        each(elems,function(i,elem,oThis){

            elem.setAttribute('overlap',i);

            var ret = objPos(elem),l=ret.left,t=ret.top,b=ret.bottom,r=ret.right;

            oThis.hostel[i]={elem:elem,leftTopDot:{x:l,y:t},leftBottomDot:{x:l,y:b},rightTopDot:{x:r,y:t},rightBottomDot:{x:r,y:b}};

        },this);

    },

    setElem:function(elem){

        if(!elem)return;

        var ret = objPos(elem),l=ret.left,t=ret.top,b=ret.bottom,r=ret.right;

        this.hostel[elem.getAttribute('overlap')] ={elem:elem,leftTopDot:{x:l,y:t},leftBottomDot:{x:l,y:b},rightTopDot:{x:r,y:t},rightBottomDot:{x:r,y:b}};

    },

 //判断是否重合     

    isOverlap : function(my){

        var obj= {}, my = this.hostel[my.getAttribute('overlap')];

        

        each(this.hostel,function(key,config,oThis){

            // 是元素本身 则返回

            if(config.elem === my.elem)return ;

   

            //判断2个div是否重合 如果不重合 则返回

            if(my.leftBottomDot.y<=config.leftTopDot.y||my.leftTopDot.y>=config.leftBottomDot.y||my.rightTopDot.x<=config.leftTopDot.x||my.leftTopDot.x>=config.rightTopDot.x)

                return;

            obj[config.elem.getAttribute('overlap')] =[config.elem,oThis.howOverlap(my,config)];

        },this);

        return obj;

    },

 //判断重合面积

    howOverlap : function(my,other){

        var l=other.leftBottomDot.x,r=other.rightTopDot.x,t=other.leftTopDot.y,b=other.leftBottomDot.y,arr=[],

        lt = this.include(my.leftTopDot,l,r,t,b,'leftTopDot-rightBottomDot'),

        lb = this.include(my.leftBottomDot,l,r,t,b,'leftBottomDot-rightTopDot'),

        rt = this.include(my.rightTopDot,l,r,t,b,'rightTopDot-leftBottomDot'),

        rb = this.include(my.rightBottomDot,l,r,t,b,'rightBottomDot-leftTopDot');

        lt&&arr.push(lt)||lb&&arr.push(lb)||rt&&arr.push(rt)||rb&&arr.push(rb);

        

        if(!arr[0]) return 0;

  //一个点 或者是 2个点都在其中  计算方法是一样的

  if(arr.length===1||arr.length===2){

   var key = arr[0].split('-'),x1=my[key[0]].x,y1=my[key[0]].y,x2=other[key[1]].x,y2=other[key[1]].y;

   return Math.abs((x1-x2)*(y1-y2));  

  };   

  //完全重合

  if(arr.length===4){

   return 162*162; 

  };  

    },

 //看点是不是在另一个div中

    include : function(dot,l,r,t,b,key){

  return (dot.x>=l&&dot.x<=r&&dot.y>=t&&dot.y<=b)?key:false;

    }

};

window.onload = function(){

    extend(Drag.options,{callbackmove:move,callbackup:up});

 

    function up(elem){

        for(var n in overlap.overlapList)

            removeClass(overlap.overlapList[n][0],'focus')

        overlap.overlapList = {};

        Drag.elem.innerHTML =Drag.elem.id;

    };

 

    function move(elem){

        overlap.setElem(elem);

        //p为判断返回的obj是不是空的

        var obj = overlap.isOverlap(elem),name,p = function(o){

            for (name in o)

                return false;

            return true;

        }(obj);    

        

        //如果是个空对象 则返回 不进行下面的遍历

        if(p){

            up();

            return;

        };

        

        var str ='';        

        overlap.overlapList = obj;

        each(overlap.hostel,function(key,config){

            if(obj[key]){

                addClass(obj[key][0],'focus');

    str = str +'与'+obj[key][0].id+'重合的面积为:'+obj[key][1]+'</br>';

            }else{

                removeClass(config.elem,'focus');

            }

        });

        Drag.elem.innerHTML = str;

    };

    Drag.init($('demo1'),$('demo2'),$('demo3'),$('demo4'),$('demo5'),$('demo6'),$('demo7'),$('demo8'),$('demo9'));

    overlap.init([$('demo1'),$('demo2'),$('demo3'),$('demo4'),$('demo5'),$('demo6'),$('demo7'),$('demo8'),$('demo9')]);

};

</script>

</body>

</html>

代码如上,只是感觉效率有点低,小伙伴们有没有什么优化方案呢,还请告之,不胜感激

Javascript 相关文章推荐
利用WebBrowser彻底解决Web打印问题(包括后台打印)
Jun 22 Javascript
23个Javascript弹出窗口特效整理
Feb 25 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
Oct 16 Javascript
JS中Iframe之间传值的方法
Mar 11 Javascript
node.js实现爬虫教程
Aug 25 Javascript
AngularJS 指令详细介绍
Jul 27 Javascript
原生js实现可拖拽效果
Feb 28 Javascript
详解Vue2 SSR 缓存 Api 数据
Nov 20 Javascript
js中switch语句的学习笔记
Mar 25 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
Jul 18 Javascript
js 图片懒加载的实现
Oct 21 Javascript
vue实现树状表格效果
Dec 29 Vue.js
javascript使用smipleChart实现简单图表
Jan 02 #Javascript
原生javascript实现简单的datagrid数据表格
Jan 02 #Javascript
浅谈jQuery事件绑定原理
Jan 02 #Javascript
js+jquery实现图片裁剪功能
Jan 02 #Javascript
javascript 构造函数方式定义对象
Jan 02 #Javascript
深入探寻javascript定时器
Jan 02 #Javascript
JavaScript中的Truthy和Falsy介绍
Jan 01 #Javascript
You might like
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
再说下636单管机
2021/03/02 无线电
php mysql Errcode: 28 终极解决方法
2009/07/01 PHP
php 保留字列表
2012/10/04 PHP
CodeIgniter框架URL路由总结
2014/09/03 PHP
PHP实现倒计时功能
2020/11/16 PHP
关于Blog顶部的滚动导航条代码
2006/09/25 Javascript
JS实现可改变列宽的table实例
2013/07/02 Javascript
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
22点关于jquery性能优化的建议
2014/05/28 Javascript
jqTransform美化表单
2015/10/10 Javascript
JavaScript中Date对象的常用方法示例
2015/10/24 Javascript
深入浅析JavaScript系列(13):This? Yes,this!
2016/01/05 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
js添加绑定事件的方法
2016/05/15 Javascript
JS中使用正则表达式g模式和非g模式的区别
2017/04/01 Javascript
让axios发送表单请求形式的键值对post数据的实例
2018/08/11 Javascript
Vue+Express实现登录状态权限验证的示例代码
2019/05/05 Javascript
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
js 函数性能比较方法
2020/08/24 Javascript
js实现炫酷光感效果
2020/09/05 Javascript
[01:00:11]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第一场 2月7日
2021/03/11 DOTA
在Python中实现贪婪排名算法的教程
2015/04/17 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
python中Lambda表达式详解
2019/11/20 Python
PyCharm 2020 激活到 2100 年的教程
2020/03/25 Python
Strawberrynet草莓网新加坡站:护肤、彩妆、香水及美发产品
2018/08/31 全球购物
Linux文件系统类型
2012/09/16 面试题
会计岗位职责
2013/11/08 职场文书
宿舍标语大全
2014/06/19 职场文书
债务授权委托书范本
2014/10/17 职场文书
统计员岗位职责范本
2015/04/14 职场文书
python实现图片九宫格分割的示例
2021/04/25 Python
python opencv旋转图片的使用方法
2021/06/04 Python
Vue图片裁剪组件实例代码
2021/07/02 Vue.js
MySQL 聚合函数排序
2021/07/16 MySQL