原生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 相关文章推荐
asp批量修改记录的代码
Jun 25 Javascript
node.js中的fs.lchownSync方法使用说明
Dec 16 Javascript
JavaScript实现三阶幻方算法谜题解答
Dec 29 Javascript
javascript实现点击提交按钮后显示loading的方法
Jul 03 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
May 05 Javascript
jQuery设置聚焦并使光标位置在文字最后的实现方法
Aug 02 Javascript
利用yarn实现一个webpack+react种子
Oct 25 Javascript
vue 系列——vue2-webpack2框架搭建踩坑之路
Dec 22 Javascript
bootstrap模态框关闭后清除模态框的数据方法
Aug 10 Javascript
JS document对象简单用法完整示例
Jan 14 Javascript
javascript实现一款好看的秒表计时器
Sep 05 Javascript
解决vant-UI库修改样式无效的问题
Nov 03 Javascript
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
php中的登陆login
2007/01/18 PHP
认识并使用PHP超级全局变量
2010/01/26 PHP
php标签云的实现代码
2012/10/10 PHP
PHP 使用header函数设置HTTP头的示例解析 表头
2013/06/17 PHP
解析在apache里面给php写虚拟目录的详细方法
2013/06/24 PHP
让你的网站可编辑的实现js代码
2009/10/19 Javascript
html 锁定页面(js遮罩层弹出div效果)
2009/10/27 Javascript
javascript 混合的构造函数和原型方式,动态原型方式
2009/12/07 Javascript
js bind 函数 使用闭包保存执行上下文
2011/12/26 Javascript
JS的replace方法介绍
2012/10/20 Javascript
JS读取XML文件示例代码
2013/11/15 Javascript
jscript读写二进制文件的方法
2015/04/22 Javascript
玩转JavaScript OOP - 类的实现详解
2016/06/08 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
2016/07/04 Javascript
浅谈javascript中的三种弹窗
2016/10/21 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
AngulerJS学习之按需动态加载文件
2017/02/13 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
用vue的双向绑定简单实现一个todo-list的示例代码
2017/08/03 Javascript
Vue工程模板文件 webpack打包配置方法
2017/12/26 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)
2018/10/08 Javascript
vue项目中常见问题及解决方案(推荐)
2019/10/21 Javascript
解决python大批量读写.doc文件的问题
2018/05/08 Python
Python函数和模块的使用总结
2019/05/20 Python
pyqt5 QProgressBar清空进度条的实例
2019/06/21 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
html5实现九宫格抽奖可固定抽中某项奖品
2020/06/15 HTML / CSS
英国最大的宝石首饰超市:QP Jewellers
2018/09/23 全球购物
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
const char*, char const*, char*const的区别是什么
2014/07/09 面试题
医科大学生的自我评价
2013/12/04 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
送达通知书
2015/04/25 职场文书
同事欢送会致辞
2015/07/31 职场文书