原生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 相关文章推荐
超级强大的表单验证
Jun 26 Javascript
在视频前插入广告
Nov 20 Javascript
JavaScript Event学习第九章 鼠标事件
Feb 08 Javascript
combox改进版 页面原型参考dojo的,比网上jQuery的那些combox功能强,代码更小
Apr 15 Javascript
js解析与序列化json数据(二)序列化探讨
Feb 01 Javascript
js监听键盘事件示例代码
Jul 26 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
Sep 23 Javascript
jQuery中contents()方法用法实例
Jan 08 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
Vuerouter的beforeEach与afterEach钩子函数的区别
Dec 26 Javascript
微信小程序实现的日期午别医生排班表功能示例
Jan 09 Javascript
javascript实现超好看的3D烟花特效
Jan 01 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系统中使用PHP 5.3之后的库
2015/12/02 PHP
php实现的双色球算法示例
2017/06/20 PHP
Laravel框架表单验证操作实例分析
2019/09/30 PHP
javascript 支持ie和firefox杰奇翻页函数
2008/07/22 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
判断访客终端类型集锦
2015/06/05 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
MVC+jQuery.Ajax异步实现增删改查和分页
2020/12/22 Javascript
EasyUI Tree树组件无限循环的解决方法
2017/09/27 Javascript
简单的Vue异步组件实例Demo
2017/12/27 Javascript
webpack公共组件引用路径简化小技巧
2018/06/15 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
详解webpack+ES6+Sass搭建多页面应用
2018/11/05 Javascript
Node.js中package.json中库的版本号(~和^)
2019/04/02 Javascript
vue实现点击按钮切换背景颜色的示例代码
2020/06/23 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
python实现的防DDoS脚本
2011/02/08 Python
闭包在python中的应用之translate和maketrans用法详解
2014/08/27 Python
python获取当前运行函数名称的方法实例代码
2017/04/06 Python
python实现日常记账本小程序
2018/03/10 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
Python读取Excel表格,并同时画折线图和柱状图的方法
2018/10/14 Python
浅析Python 3 字符串中的 STR 和 Bytes 有什么区别
2018/10/14 Python
Django后端发送小程序微信模板消息示例(服务通知)
2019/12/17 Python
Python运行DLL文件的方法
2020/01/17 Python
如何基于Python实现数字类型转换
2020/02/07 Python
python pymysql链接数据库查询结果转为Dataframe实例
2020/06/05 Python
python ETL工具 pyetl
2020/06/07 Python
HTML5使用drawImage()方法绘制图像
2014/06/23 HTML / CSS
Baracuta官方网站:Harrington夹克,G9,G4,G10等
2018/03/06 全球购物
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
机关作风建设自查报告
2014/10/22 职场文书
2016大学自主招生推荐信范文
2015/03/23 职场文书
品牌形象定位,全面分析
2019/07/23 职场文书
读《方与圆》有感:交友方圆有度
2020/01/14 职场文书
Python爬取某拍短视频
2021/06/11 Python