写了一些判断 但是感到不大理想 每次拖动的时候都要去遍历 效率确实不好
各位前辈们
给些思路 也行 说说想法也好 指出下代码出写的不好的地方也好 总之 指教下可以直接看效果部分代码 全部代码发不下
(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));
}
};window.each = function ( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
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(){
if(arguments.length===1){
addListener(arguments[0],'mousedown',BindAsEventListener(this,this.start,arguments[0]));
}else if(arguments.length>1){
for(var i=0,l=arguments.length;i<l;i++)
addListener(arguments[i],'mousedown',BindAsEventListener(this,this.start,arguments[i]));
}
},
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));
},
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 ;
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;
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));
},
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);
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')]);
};
各位前辈们
给些思路 也行 说说想法也好 指出下代码出写的不好的地方也好 总之 指教下可以直接看效果部分代码 全部代码发不下
(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));
}
};window.each = function ( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
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(){
if(arguments.length===1){
addListener(arguments[0],'mousedown',BindAsEventListener(this,this.start,arguments[0]));
}else if(arguments.length>1){
for(var i=0,l=arguments.length;i<l;i++)
addListener(arguments[i],'mousedown',BindAsEventListener(this,this.start,arguments[i]));
}
},
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));
},
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 ;
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;
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));
},
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);
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')]);
};
1)假设初始时所有 div 之间都不重叠;
2)遍历所有 div,依次记录其所占的区域坐标(LeftTop, RightBottom),如 AreaList[9];
3)当任意 div 拖动结束时,获取当前 div 的区域坐标,依次与 AreaList[9] 中除了自己以外区域进行重叠判断(lz 应该已经实现了),并保存检查结果;
4)输出检查结果;
5)完毕。lz 觉得如何?!
你的意思是
拖动的过程中 还没有释放鼠标吧思路跟你差不多
但是第3步的优化比较麻烦 里面细节太多.......
Fires on the source object when the user releases the mouse at the close of a drag operation.即刚刚释放鼠标左键时触发,至于 FF 俺就不清楚了!DHTML 参考手册
http://download.csdn.net/source/308913
那就是鼠标移动的时候不去计算面积了 这样好像做不到即使改变了 就是拖动中改变恩 我把边框重合的情况去掉了 因为会这样会存在2个div重合的情况 我闲麻烦就去掉了
既然你发现了 我还是改过来好了
遍历注册的观察者通知其检查是否重合。似乎遍历在所难免!
我知道ext js 框架实现的拖动效果非常好
我试过一些,希望对lz有用
?method=flickr.photos.search
&api_key=85618ad7d326d8ef93c6bee9ed32706f
&per_page=5&format=json&text=china下面这个URL发送到Google Base,它允许开发人员使用自己定义的回调函数:http://www.google.com/base/feeds/snippets
?q=jquery
&alt=json-in-script
&callback=customCallback把前面的URL放到浏览器地址栏中,回车,即可看到结果。