js简单的切割效果和容器的拖拽

来源:互联网 发布:耐克淘宝正品店 编辑:程序博客网 时间:2024/06/05 20:55

参考:cloudgamer大神的博文(推荐)。

事件绑定:bind和bindAsEventListener。

bind(obj,fun)可以将函数fun绑定到对象obj上,但是在fun函数中绑定参数。

function bind(obj,fun) //将函数fun绑定到某个对象obj{return function(){return fun.apply(obj,arguments);}}

bindAsEventListener(obj,fun)同bind可以将函数fun绑定到对象obj上,但是可以在fun函数中绑定参数,同时会将event作为第一个参数。

var bindAsEventListener = function(obj, fun) //将函数绑定到对象的某个事件上,作为事件处理函数{var args = Array.prototype.slice.call(arguments).slice(2);return function(event) {return fun.apply(obj, [event || window.event].concat(args));}}
如果传入参数形如bindAsEventListener(this,this.clickEvent,name,age....)的形式。那么bindAsEventListener首先会利用Array.prototype.slice.call(argument).slice(2)的方法,将arguments作为一个参数列表,利用call方法将arguments参数列表转化成为数组的参数传入到Array中去,然后再可以调用Array.slice(2)的方法截取从[2,arguments.length)的参数。具体测试代码为:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><script type="text/javascript">var array=new Array(1,2,3,4,5,6,7);array=array.slice(2); //截取数组[2,array.length)中的数据//alert(array);function  test(a,b,name,age,password){alert(arguments); //arguments可以获取所有的参数列表alert(Array.prototype.slice.call(arguments).slice(2)); //截取从[2,arguments.length)的参数列表,弹出xuzengqiang,12,123456}test(1,2,"xuzengqiang",12,"123456");</script><body></body></html>
bindAsEventListener最后的return语句中apply的参数列表为[event ||  window.event].contact(args);这里表示将event事件作为fun的第一个参数。args保存的参数列表作为fun的后续参数。

bindAsEventListener和bind的测试用例如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>无标题文档</title></head><script type="text/javascript">var bind=function(obj,fun)  //将函数fun绑定到对象obj上{return function(){return fun.apply(obj,arguments);}}var bindAsEventListener=function(obj,fun) {var args = Array.prototype.slice.call(arguments).slice(2);return function(event) {return fun.apply(obj, [event || window.event].concat(args)); //将事件event绑定到eventFun作为第一个参数}}var Class={create:function(){return function(){this.initialize.apply(this,arguments);}}};var bindTest=Class.create();bindTest.prototype={initialize:function(obj){var $button=document.getElementById(obj);var name="xuzengqiang";//$button.onclick=bindAsEventListener(this,this.clickEvent,name); //name作为clickEvent的参数$button.onclick=bind(this,this.bindClick);},clickEvent:function(e,name){alert(name+"你竟敢点击我!");},bindClick:function(){alert("绑定点击事件!");}}window.onload=function(){new bindTest("bind");}</script><body><button id="bind">点击</button></body></html>

效果图预览:其中8个点可以任意方向拖动,用来改变容器大小,容器本身可以拖动。

实现:主要利用methoBind()绑定8个方向点的拖动函数,通过mousedown事件来触发this.dataInit进行数据初始化开始缩放,

this.dataInit主要设置缩放程序this._fun和缩放参数,然后利用mousemove事件触发resize方法进行拖放后容器样式的设置,mouseup触发Stop方法停止拖放。

缩放原理:

以向上拖动和向下拖动为例:

向上拖动的时候:下侧必须固定,同时高度也要发生变化

方式一:自增或自减,每次更新拖动前后的坐标,然后让高度自增或自减拖动前后的坐标差值,这样做相对而言叫麻烦,但是思路清晰,需要每次都更新拖动前的坐标,将这次拖动后的坐标作为下一次拖动前的坐标。

方式二:只记录鼠标按下时坐标位置,然后每次鼠标拖动的时候,只记录每次拖动后的坐标与鼠标按下时坐标和容器高度的变化,不需要进行高度自增或自减操作,只需进行赋值即可。推荐方式二:

首先记录高度的变化:

this.styleHeight=Math.max(this.sideDown-e.clientY,0);

top值的变化:(其中this.bottomPosition表示最底边的高度位置)

this.styleTop=this.bottomPosition-this.styleHeight;

top值和容器高度变化的分析:


向下拖动,这时候保证顶部不移动,top值不用发生改变,只需修改高度即可。

<span style="font-family:Microsoft YaHei;">this.styleHeight=Math.max(e.clientY-this.sideUp,0);</span>
高度分析:


其它方向分析同理。

div层的拖动原理:只需修改left和top值,width和height不会发生改变。

方式一:获取鼠标拖动前位置(startX,startY),然后当鼠标拖动的时候记录拖动后的坐标(e.clientX,e.clientY)。这个时候容器的left和top分别自增对应坐标的差值即可。

每拖动一次重新修改startX=e.clientX,startY=e.clientY即可。

this.styleLeft+=e.clientX-this.startX;this.styleTop+=e.clientY-this.startY;this.startX=e.clientX;this.startY=e.clientY;  

方式二:同样只需记录鼠标按下的坐标,然后记录每次鼠标拖动后的坐标(e.clientX,e.clientY),找出拖动后的坐标与鼠标按下坐标和left、top值的关系。

以left变更为例:

this.styleLeft=e.clientX-this.dragLeft;

分析:


完整代码:(css样式方面不做分析)

<!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>test</title>  <style type="text/css">  *{margin:0;padding:0}  .borderDiv{width:100px;height:100px;border:1px dashed #AFAFAF;position:absolute;top:100px;left:30px;cursor:move;z-index:4;}  .move{width:6px;height:6px;background:#FFFFFF;border:2px solid #AFAFAF;position:absolute;border-radius:10px;z-index:5;}  .left,.right{cursor:e-resize;top:50%;margin-top:-5px;}  .leftBottomMove,.rightTopMove{cursor:ne-resize}  .leftTopMove,.rightBottomMove{cursor:nw-resize}  .top,.bottom{cursor:n-resize}  .leftTopMove{top:-5px;left:-5px;}  .top{left:50%;margin-left:-5px;top:-5px}  .rightTopMove{right:-5px;top:-5px}  .left{left:-5px}  .right{right:-5px}  .leftBottomMove{bottom:-5px;left:-5px}  .bottom{bottom:-5px;left:50%;margin-left:-5px}  .rightBottomMove{bottom:-5px;right:-5px}  </style>  </head>    <script type="text/javascript"> var isIE=(document.all)?true:false; function $(){if(arguments.length==1 && typeof arguments[0] == "string"){return document.getElementById(arguments[0]);}};var Class={create:function(){return function(){this.initialize.apply(this,arguments);}}};Object.extend=function(destination,source) {for(var property in source){destination[property]=source[property];}return destination;};Object.prototype.extend=function(obj){return Object.extend.apply(this,[this,obj]);};var Event=(function(){return {addEventHandler:function(target,eventType,fun) {if(target.addEventListener){target.addEventListener(eventType,fun,false);}else if(target.attachEvent){target.attachEvent("on"+eventType,fun);}else{target["on"+eventType]=fun;}},removeEventHandler:function(target,eventType,fun){if(target.removeEventListener){target.removeEventListener(eventType,fun,false);}else if(target.detachEvent){target.detachEvent("on"+eventType,fun);}else{target["on"+evenetType]=false;}}}}());function bind(obj,fun) //将函数fun绑定到某个对象obj{return function(){return fun.apply(obj,arguments);}}var bindAsEventListener = function(obj, fun) //将函数绑定到对象的某个事件上,作为事件处理函数{var args = Array.prototype.slice.call(arguments).slice(2);return function(event) {return fun.apply(obj, [event || window.event].concat(args));}}//扩展document中的getElementsByClassName方法,即通过class类名的值获取元素对象document.getElementsByClassName=function(className){var elements=new Array(),allElements=document.getElementsByTagName('*') || document.all; for(var i=0,maxLen=allElements.length; i<maxLen; i++){var child=allElements[i],classNames=child.className.split(' '); for(var j=0,max=classNames.length;j<max;j++) //不推荐for(var j=0;j<classNames.length;j++)方式,因为每次都会计算长度{if(className==classNames[j]){elements.push(child);break;}}}return elements;}var SimpleDrag=Class.create();SimpleDrag.prototype={initialize:function(obj,options) //obj为容器对象,{this.content=$(obj);this._resize = bindAsEventListener(this,this.resize);this._stop = bind(this,this.Stop);},setOptions:function(options) //参数设置{},methodBind:function(obj) //八个方向点方法绑定 {var current=document.getElementsByClassName(obj)[0],fun; //fun为方法if(!current) return ;switch(obj){case "top":fun=this.up;break;case "bottom":fun=this.down;break;case "left":fun=this.left;break;case "right":fun=this.right;break;case "leftTopMove":fun=this.leftUp;break;case "rightTopMove":fun=this.rightUp;break;case "leftBottomMove":fun=this.leftDown;break;case "rightBottomMove":fun=this.rightDown;break;default: //否则对容器对象进行拖拽fun=this.drag;}Event.addEventHandler(current,"mousedown",bindAsEventListener(this,this.dataInit,fun)); //fun作为dataInit的参数},dataInit:function(e,fun) //数据初始化{//防止事件冒泡,IE:e.cancelBubble=true,FF:e.stopPropagation()e.stopPropagation?e.stopPropagation():(e.cancelBubble=true);this._fun=fun;this.styleWidth=this.content.clientWidth; //容器可以宽度,不包括边框和滚动条this.styleHeight=this.content.clientHeight;this.styleLeft=this.content.offsetLeft; //容器向左偏移的距离this.styleTop=this.content.offsetTop;this.sideLeft = e.clientX - this.styleWidth; //左侧定位参数,e.clientX表示事件发生位置相对于浏览器的横坐标this.sideRight = e.clientX + this.styleWidth;this.sideUp = e.clientY - this.styleHeight;this.sideDown = e.clientY + this.styleHeight;this.dragLeft=e.clientX-this.styleLeft;this.dragTop=e.clientY-this.styleTop;this.rightPosition=this.styleWidth+this.styleLeft; //最右边的位置this.bottomPosition=this.styleHeight+this.styleTop; //最底部的位置Event.addEventHandler(document,"mousemove",this._resize);Event.addEventHandler(document,"mouseup",this._stop);},resize:function(e) //当拖动后重新修改容器的大小{this._fun(e); //改变with(this.content.style){width=this.styleWidth+"px",height=this.styleHeight+"px";top=this.styleTop+"px",left=this.styleLeft+"px";}},up:function(e) //向上移动,此时容器的top值也要随之改变,从而保证下侧固定{this.styleHeight=Math.max(this.sideDown-e.clientY,0);this.styleTop=this.bottomPosition-this.styleHeight;},down:function(e){this.styleHeight=Math.max(e.clientY-this.sideUp,0);},left:function(e){this.styleWidth=Math.max(this.sideRight-e.clientX,0);this.styleLeft=this.rightPosition-this.styleWidth;},right:function(e){this.styleWidth=Math.max(e.clientX-this.sideLeft,0);},leftUp:function(e){this.left(e);this.up(e);},rightUp:function(e){this.right(e);this.up(e);},leftDown:function(e){this.left(e);this.down(e);},rightDown:function(e){this.right(e);this.down(e);},drag:function(e){this.styleLeft=e.clientX-this.dragLeft;this.styleTop=e.clientY-this.dragTop;},Stop:function() //停止缩放{Event.removeEventHandler(document,"mousemove",this._resize);Event.removeEventHandler(document,"mouseup",this._stop);}}window.onload=function(){var resize=new SimpleDrag("borderDiv");resize.methodBind("top"); //向上移动resize.methodBind("bottom"); //向下移动resize.methodBind("left"); //向左移动resize.methodBind("right"); //向右移动resize.methodBind("leftTopMove");resize.methodBind("rightTopMove");resize.methodBind("leftBottomMove");resize.methodBind("rightBottomMove");resize.methodBind("borderDiv");}</script>  <body style="">  <div class="borderDiv" id="borderDiv">  <div class="leftTopMove move"></div>  <div class="top move"></div>  <div class="rightTopMove move"></div>  <div class="left move"></div>  <div class="right move"></div>  <div class="leftBottomMove move"></div>  <div class="bottom move"></div>  <div class="rightBottomMove move"></div> </div> </body>  </html>  





0 0
原创粉丝点击