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>
- js简单的切割效果和容器的拖拽
- jQuery拖拽效果和切割效果
- JS 简单的拖拽移动效果
- js:简单的拖动效果
- 简单的js打印机效果
- js实现简单的checkbox全选和取消全选效果
- css和js实现最简单的轮播图效果
- js的拖拽效果
- ClipDrawable的用法(图片切割效果)
- js 的简单的图片预览效果
- JS 滤镜切割图片效果。
- 简单实用的js缓冲效果
- js简单的缓动效果
- 简单的Js图片轮播效果
- 非常简单的JS分页效果
- JS实现简单的打字效果
- 通过js实现简单的动画效果
- js---练习,简单的落叶效果
- XMPPFrameWork IOS 开发(七)消息回执
- nekohtml中解析中出现中文乱码问题
- 程序自删除
- Oracle EBS SLA 详解
- 基于MQTT协议的 org.eclipse.paho.client.mqttv3 源码学习(二)
- js简单的切割效果和容器的拖拽
- VC实现可在VB中调用的DLL
- linux下获取ip地址的命令行
- 第十一周项目2-职员信息
- 转:SRILM语言解读
- curl 命令使用
- jsp新手版
- 天气越来越热了,好想脱了啊,凉快一下
- jsp 常用的鼠标样式