• 自己写一个jqery的拖拽插件


    说实话,jQuery比原生的js好用多了,本来想用原生写的,也写出来的,仅仅是,感觉不像插件,所以用jQuery实现了一版。

    实现的功能:能够指定拖拽的边界,在拖拽过程中,能够触发几个自己定义事件

    先说明一下我写的插件的原则:

    1.常量分离出来,放在$.zUI.插件中

    2.插件的主体运行函数命名为$.zUI.插件.fn

    3.销毁函数命名为$.zUI.插件.unfn

    这些规范,主要是为了以后写其它插件时,放在一起,精简代码用的,以后可能还会添加�其它规则,以写出一个骨架来。

    拖拽的原理事实上比較简单,就是在鼠标落下后,加入�一个mousemove事件,让元素尾随鼠标移动,鼠标抬起后,移除刚才的事件。别看以下的代码那么多,事实上多数是控制元素拖拽的范围的,把这些代码忽略后,其余的东西,非常少。

    基本的两段代码例如以下:

    		$.zUI = $.zUI || {}
    		/*
    		 * draggable
    		 * 參数:obj{
    		 * bOffsetParentBoundary:是否以定位父亲元素为边界,
    		 * oBoundary:指定元素left和top的边界值,形如{iMinLeft:...,iMaxLeft:...,iMinTop:...,iMaxTop:...},与上一个參数相互排斥
    		 * fnComputePosition:扩展函数,返回形如{left:...,top:...}的对象
    		 * }
    		 * 支持的自己定义事件:
    		 * "draggable.start":drag起始,就是鼠标down后触发
    		 * "draggable.move":drag过程中多次触发
    		 * "draggable.stop":drag结束触发,就是鼠标up后触发
    		 */
    		//draggable常量
    		$.zUI.draggable = {
    			defaults :{
    				bOffsetParentBoundary:false,//是否以定位父亲元素为边界
    				oBoundary:null,//边界
    				fnComputePosition:null//计算位置的函数
    			},
    			sFlagName:"zUIdraggable",
    			sEventName:"zUIdraggableEvent",
    			sOptsName:"draggableOpts"
    		}
    		$.zUI.draggable.fn = function(ele,opts){
    
    			var jqEle = $(ele);
    			jqEle.data($.zUI.draggable.sOptsName,$.extend({},$.zUI.draggable.defaults,opts));
    			//假设该參数已经运行过draggable了,直接返回,仅相当于改动了配置參数
    			if(jqEle.data($.zUI.draggable.sFlagName)){
    				return;
    			}
    			jqEle.data($.zUI.draggable.sFlagName,true);
    			jqEle.data($.zUI.draggable.sEventName,{
    				mousedown:function(ev){
    				var opts = jqEle.data($.zUI.draggable.sOptsName);
    				var jqThis = $(this);
    				jqThis.trigger("draggable.start");
    				var iOffsetX = ev.pageX - this.offsetLeft;
    				var iOffsetY = ev.pageY - this.offsetTop;
    				
    				function fnMouseMove (ev) {
    					var oPos = {};
    					if(opts.fnComputePosition){
    						oPos = opts.fnComputePosition(ev,iOffsetX,iOffsetY);
    					}else{
    						oPos.iLeft = ev.pageX - iOffsetX;
    						oPos.iTop = ev.pageY - iOffsetY;
    					}
    					
    					var oBoundary = opts.oBoundary;
    					if(opts.bOffsetParentBoundary){//假设以offsetParent作为边界
    						var eParent = jqThis.offsetParent()[0];
    						oBoundary = {};
    						oBoundary.iMinLeft = 0;
    						oBoundary.iMinTop = 0;
    						oBoundary.iMaxLeft = eParent.clientWidth - jqThis.outerWidth();
    						oBoundary.iMaxTop = eParent.clientHeight - jqThis.outerHeight();
    					}
    
    					if(oBoundary){//假设存在oBoundary,将oBoundary作为边界
    						oPos.iLeft = oPos.iLeft < oBoundary.iMinLeft ? oBoundary.iMinLeft : oPos.iLeft;
    						oPos.iLeft = oPos.iLeft > oBoundary.iMaxLeft ? oBoundary.iMaxLeft : oPos.iLeft;
    						oPos.iTop = oPos.iTop < oBoundary.iMinTop ? oBoundary.iMinTop : oPos.iTop;
    						oPos.iTop = oPos.iTop > oBoundary.iMaxTop ? oBoundary.iMaxTop : oPos.iTop;
    					}
    					
    					jqThis.css({left:oPos.iLeft,top:oPos.iTop});
    					ev.preventDefault();
    					jqThis.trigger("draggable.move");
    				}
    				
    				var oEvent = {
    					mousemove:fnMouseMove,
    					mouseup:function(){
    						$(document).off(oEvent);
    						jqThis.trigger("draggable.stop");
    					}
    				};
    
    				$(document).on(oEvent);
    			}});
    			
    			jqEle.on(jqEle.data($.zUI.draggable.sEventName));
    		}
    		
    		$.zUI.draggable.unfn = function(e){
    			var jqEle = $(ele);
    			if(jqEle.data($.zUI.draggable.sFlagName)){
    				jqEle.off(jqEle.data($.zUI.draggable.sEventName));
    				jqEle.data($.zUI.draggable.sFlagName,false);
    			}
    		}

    须要说明的有几点:

    1.鼠标落下后,要记录鼠标相对元素的位置,mousemove的过程中,要把这段距离减去;

    2.jQuery的data方法,这种方法很方便,能够讲数据和相应的元素绑定,jq.data(key,value)就出存储,jq.data(key)就是读取,jq.data(obj)也是存储。

    3.undraggable就是把事件函数去掉了

    4.jQuery的on方法很强大,加入�后还能够使用trigger方法来触发,有兴趣的同学能够到官方看看API,on方法很暴躁,这里的自己定义函数,就是用这两个方法实现的。

    5.这里是把方法放在了$函数上,最后要把这种方法放在$.fn上,例如以下:

    $.each(["draggable"],function(i,widget){
    			unWidget = "un"+widget;
    			var w = {};
    			w[widget] = function(args){
    					this.each(function(){
    					$.zUI[widget].fn(this,args);
    				});
    				return this;
    			};
    			w[unWidget] = function(){
    					this.each(function(){
    					$.zUI[unWidget].unfn(this);
    				});
    				return this;
    			}
    			$.fn.extend(w);
    		});

    这里是不是有点乱,事实上这么写主要是为了以后写方便;

    each除了在jq对象上用之外,还能够使用$.each(Array,fnCallBack);之后加入�新的插件后,依照我之前的标准写,仅仅须要在第一个參数上加入�其它字符串就能够了。

    细致看看,就是加入�了两个方法:draggable和undraggable;这两函数都调用this.each方法,让dragable和undraggable能够再每一个元素上都运行。


    最后,用一个匿名函数自运行把他们都包起来,为了防止$符号被其它的插件使用,传一个jQuery过去:

    (function($){
              .......		
    })(jQuery);
    	

    到此为止,这个插件就写完啦。以下是demo的链接地址。

    拖拽demo


  • 相关阅读:
    动态规划算法-3
    动态规划算法-2
    动态规划算法-1
    滑动窗口算法-3
    央行副行长提示金融风险:地方偿债高峰期到来
    银行卡换“芯” 更要银行换心
    破解IT运维成本困境,专业化分工是妙方
    php连接mysql
    ajax原生验证用户名是否存在
    ajax跨域问题
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4027983.html
Copyright © 2020-2023  润新知