自己写一个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的链接地址。
自己写一个jqery的拖拽插件的更多相关文章
- 自己写一个jQuery垂直滚动栏插件(panel)
html中原生的滚动栏比較难看,所以有些站点,会自己实现滚动栏,导航站点hao123在一个側栏中,就自己定义了垂直滚动栏,效果比較好看,截图例如以下: watermark/2/text/aHR0cDo ...
- jQuery网页元素拖拽插件
效果说明:配合已有CSS样式,载入插件后,网页元素可以随意在窗口内拖拽,设置了原位置半透明和拖拽半透明的效果选项,可根据需要选择.另外,当页面上有多个可拖拽元素时,可以载入另外一个用于设置z-inde ...
- 网站开发常用jQuery插件总结(三)拖拽插件gridster
1.gridster插件功能 实现类似于win8 磁贴拖拽的功能 2.gridster官方地址 http://gridster.net/ 在官方的网站上也有插件的帮助和实例,但是按照官方的说明,我在本 ...
- Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现
Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...
- JQuery之拖拽插件
一直以来,都对JS获取元素的位置感到非常的困惑:一会client.一会offset.一会scroll. 再加上各大浏览器之间的不兼容,唉,搞得哥晕晕乎乎的. 而很多页面效果都要用到这些位置.不得已,得 ...
- 一步一步实现JS拖拽插件
js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...
- vue拖拽插件(弹框拖拽)
// =======拖拽 插件 cnpm install vuedraggableimport draggable from 'vuedraggable' <draggable v-model= ...
- 从0开始写一个简单的vite hmr 插件
从0开始写一个简单的vite hmr 插件 0. 写在前面 在构建前端项目的时候,除开基本的资源格式(图片,json)以外,还常常会需要导入一些其他格式的资源,这些资源如果没有第三方vite插件的支持 ...
- 自制一个H5图片拖拽、裁剪插件(原生JS)
前言 如今的H5运营活动中,有很多都是让用户拍照或者上传图片,然后对照片加滤镜.加贴纸.评颜值之类的.尤其是一些拍照软件公司的运营活动几乎全部都是这样的. 博主也做过不少,为了省事就封装了一个简单的图 ...
随机推荐
- Android Matrix(坐标矩阵)
Android Matrix 2016-02-26 14:38:10 介绍 中文名:坐标矩阵 高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matr ...
- docker学习笔记7:发布镜像到docker hub上
镜像创建好后,很重要的一个操作就是共享和发布.可以将自己创建的镜像发布到docker hub上,也可以发布到自己的私有docker hub上. 要想发布镜像到dokcer hub上,首先要在dokce ...
- 又见拦截导弹(LIS)
又见拦截导弹 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 大家对拦截导弹那个题目应该比较熟悉了,我再叙述一下题意:某国为了防御敌国的导弹袭击,新研制出来一种导弹拦截系 ...
- Android 自动编译、打包生成apk文件 4 - 多渠道批量打包
相关文章列表: < Android 自动编译.打包生成apk文件 1 - 命令行方式> < Android 自动编译.打包生成apk文件 2 - 使用原生Ant方式 > < ...
- java --对象流与对象的序列化
对象流 ObjectInputStream ObjectOutputStream类分别是InputStream和OutputStream的子类,对象输出流使用writeObject(Object ob ...
- 织梦sitemap模板获取文章列表
分析了一下makehtml_map.php?dopost=site这个文件,发现生成视图用的是dedetag.class.php文件,有点简单.不能使用织梦的很多标签,例如: {dede:arclis ...
- 终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)——消息是否继续传递就看这个Result
Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型, 而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样. t ...
- 高级特性(2)- XML
2.1 概述2.2 解析XML文档2.3 验证XML文档 2.3.1 文档类型定义 2.3.2 XML Schema 2.3.3 实用示例2.4 使用XPath来定位信息2.5 使用命名空间2.6 流 ...
- asp.net2.0安全性(2)--用户个性化设置(2)--转载来自车老师
上一篇我们用Profile.age等方式可以读取用户的年龄和其它的信息,但有的时候我们要查询显示所有用户的信息,但asp.net没有提供查询所有用户信息的功能,我们只能对现有的用户逐一查询其Profi ...
- 80 多个 Linux 系统管理员必备的监控工具
随着互联网行业的不断发展,各种监控工具多得不可胜数.这里列出网上最全的监控工具.让你可以拥有超过80种方式来管理你的机器.在本文中,我们主要包括以下方面: 命令行工具 网络相关内容 系统相关的监控工具 ...