自己写一个jqery的拖拽插件

自己写一个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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118261.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab 关闭axis的图,使用MATLAB中axis实现图形坐标控制[通俗易懂]

    matlab 关闭axis的图,使用MATLAB中axis实现图形坐标控制[通俗易懂]Matlab对图形风格的控制比较完备。一方面,在最通用的层面上,采用了一系列考虑周全的默认设置。另一方面,可用户根据需要去自己设置。坐标控制指令axis使用比较简单,用于控制坐标的可视,取向、取值范围和轴的高宽比等。代码实现程序如下:clearall;closeall;clc;t=0:2*pi/99:2*pi;x=1.5*cos(t);y=3.25*sin(t);subplot(2,3,…

    2022年5月20日
    42
  • Idea生成Javadoc

    Idea生成Javadoc

    2022年3月12日
    35
  • python3异常可直接抛出_python自定义异常

    python3异常可直接抛出_python自定义异常python抛出异常的方法发布时间:2020-08-1411:10:34来源:亿速云阅读:89作者:小新这篇文章主要介绍python抛出异常的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!异常是Python对象,表示一个错误。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。python学习网,大量的免费python视频教程,欢迎在线学习!常见异常#…

    2022年10月18日
    0
  • 海外代理服务器有哪些好处?[通俗易懂]

    海外代理服务器有哪些好处?[通俗易懂]国外代理服务器的配置分为服务器端和客户端两部分,其中服务器端的配置包括用户创建、管理、监控、统计、分析、查询等功能。但是,这一工作通常都是由因特网服务商或专门的网络管理员来完成,对于一般拨号用户来说,海外代理服务器的配置实际上是指客户机的配置,具体的好处包括以下几点。1、能够有效地提高访问速度。一般来说,最好的海外代理服务器会预先设置一个更大的硬盘缓冲区,以便能够容纳足够多的数据,因此,当有外来信息通过时,该缓冲区的容量非常大,便于将外来信息保存到缓冲区中。国外代理服务器采用这种方式,当又有其他用户可.

    2022年6月8日
    40
  • cas6.2 客户端配置时候出现的问题 the trustAnchors parameter must be non-empty 和 PKIX path building failed

    cas6.2 客户端配置时候出现的问题 the trustAnchors parameter must be non-empty 和 PKIX path building failed

    2020年11月9日
    203
  • C#操作xml文件:使用XmlDocument 实现读取和写入

    C#操作xml文件:使用XmlDocument 实现读取和写入XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极…

    2022年6月22日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号