原生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 相关文章推荐
javascript中的一些注意事项 更新中
Dec 06 Javascript
jQuery学习笔记 获取jQuery对象
Sep 19 Javascript
动态添加option及createElement使用示例
Jan 26 Javascript
jQuery 插件开发指南
Nov 14 Javascript
JavaScript设计模式之建造者模式介绍
Dec 28 Javascript
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
原生 JS Ajax,GET和POST 请求实例代码
Jun 08 Javascript
jquery获取easyui日期控件的值实现方法
Nov 09 Javascript
js实现数组去重方法及效率?Ρ? target=
Feb 14 Javascript
vue实现表格数据的增删改查
Jul 10 Javascript
浅析js中mvvm模式实现的原理
Oct 06 Javascript
详解Vue 的异常处理机制
Nov 30 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
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
smarty内置函数{loteral}、{ldelim}和{rdelim}用法实例
2015/01/22 PHP
PHP实现根据图片色界在不同位置加水印的方法
2015/08/08 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
2016/05/28 PHP
使用Modello编写JavaScript类
2006/12/22 Javascript
js程序中美元符号$是什么
2008/06/05 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
JS获取整个页面文档的实现代码
2011/12/15 Javascript
一个通过script自定义属性传递配置参数的方法
2014/09/15 Javascript
Javascript获取CSS伪元素属性的实现代码
2014/09/28 Javascript
jquery checkbox 勾选的bug问题解决方案与分析
2014/11/13 Javascript
js简单抽奖代码
2015/01/16 Javascript
Javascript验证Visa和MasterCard信用卡号的方法
2015/07/27 Javascript
基于jQuery实现的向下滑动二级菜单效果代码
2015/08/31 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
2016/08/23 Javascript
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
Vue2.0实现组件数据的双向绑定问题
2018/03/06 Javascript
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
python动态性强类型用法实例
2015/05/09 Python
Python实现控制台进度条功能
2016/01/04 Python
Windows中安装使用Virtualenv来创建独立Python环境
2016/05/31 Python
浅谈python为什么不需要三目运算符和switch
2016/06/17 Python
浅谈Scrapy框架普通反爬虫机制的应对策略
2017/12/28 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
python3+PyQt5实现拖放功能
2018/04/24 Python
HTML5 用动画的表现形式装载图像
2016/03/08 HTML / CSS
爱尔兰灯和灯具网上商店:Lights.ie
2018/03/26 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
财务主管岗位职责
2014/02/28 职场文书
帮一个朋友写的求职信
2014/08/09 职场文书
后勤管理员岗位职责
2014/08/27 职场文书
《全神贯注》教学反思
2016/02/22 职场文书
2016年优秀教师先进事迹材料
2016/02/26 职场文书
Python中Matplotlib的点、线形状、颜色以及绘制散点图
2022/04/07 Python
原生JS实现分页
2022/04/19 Javascript