一个简单的jQuery插件制作 学习过程及实例


Posted in Javascript onApril 25, 2010

一,首先,制作jQuery插件需要一个闭包

(function ($) { 
//code in here 
})(jQuery);

这是来自jQuery官方的插件开发规范要求,使用这种编写方式有什么好处呢?
a) 避免全局依赖。
b) 避免第三方破坏。
c) 兼容jQuery操作符'$'和'jQuery '

二,有了闭包,在其中加入插件的骨架

$.fn.dBox = function (options) { 
var defaults = { 
//各种属性及其默认值 
}; 
var opts = $.extend(defaults, options); 
//function codes in here 
};

在这里dBox是我为这个弹出层插件的命名

三,为dBox建立起属性及其默认值

$.fn.dBox = function (options) { 
var defaults = { 
opacity: 0.6, //for mask layer 
drag: true, 
title: 'dBox', 
content: '', 
left: 400, 
top: 200, 
width: 600, 
height: 300, 
setPos: false, //if use the customer's left and top 
overlay: true, //if use the mask layer 
loadStr: 'Loading', 
ajaxSrc: '', 
iframeSrc: '' 
}; 
var opts = $.extend(defaults, options); 
//function codes in here 
};

四,既然是弹出窗体,那么要先设计好一个div窗体和遮罩层,在这里我将样式也直接写进去了,在function codes区域中输入如下:
//build html code of the dBox 
var dBoxHtml = "<div id='dBox' style='background-color:#FFF;border:solid 2px #00E;position:absolute;z-index:100;'>"; 
dBoxHtml += "<div id='d_head' style='width:100%;height:20px;border-bottom:solid 1px #00E;'>"; 
dBoxHtml += "<div id='d_title' style='float:left;width:90%;color:#00E'>" + opts.title + "</div>"; 
dBoxHtml += "<div id='d_close' style='float:right;cursor:pointer;margin-right:5px;color:#00E'>[x]</div>"; 
dBoxHtml += "</div>"; 
dBoxHtml += "<div id='d_content' style='width:100%;height:100%;padding:3px;'>" + opts.content + "</div>"; 
dBoxHtml += "</div>"; 
var dBoxBG = "<iframe id='d_iframebg' style='position:absolute;top:0;left:0;width:0;height:0;border:none;'></iframe><div id='d_bg' style='background-color:#000;z-index:99;position:absolute;top:0;left:0;'></div>"; 
var loading = "<div id='d_loading' style='position:fixed;top:48%;left:48%;z-index:100;border:solid 1px #000;'>" + opts.loadStr + "</div>";

在IE6中,z-index对下拉列表不会起作用,所以这里遮罩层中加入id为d_iframebg的iframe作为遮罩层,这样,大体已经制作好了框架。
五,现在我们考虑要实现什么功能了
首先,如何出现弹出窗体,一般都是点击,这里仍然使用点击事件
//click event 
$(this).click(function () { 
$("body").append(dBoxHtml); 
//case ajax 
if (opts.ajaxSrc != "") { 
$("#d_content").append("<div id='d_ajax' style='width:" + (opts.width - 6) + "px;height:" + (opts.height - 26) + "px;overflow:scroll;'><div id='d_ajaxcontent'></div></div>"); 
$("#d_ajaxcontent").load(opts.ajaxSrc); 
} 
//case iframe 
else if (opts.iframeSrc != "") { 
$("#d_content").append("<iframe frameborder='0' width='" + (opts.width - 6) + "' height='" + (opts.height - 26) + "' src='" + opts.iframeSrc + "'>"); 
} 
addCSS(); 
//case drag 
if (opts.drag == true) { 
drag(); 
} 
$("#d_close").click(dBoxRemove); 
return false; 
});

最后一个return false可以去掉浏览器默认的点击事件,如在一个a标记上绑定点击事件,将不会造成默认的跳转效果
在这个点击事件中,先将dBox的框架载入了页面,然后判断内容的加载方式,分别处理,最后有三个事件
1,addCSS()此事件处理遮罩层大小,弹出层的位置
2,drag()此事件处理弹出层的拖曳
3,dBoxRemove()此事件处理弹出层的关闭
有了这三个事件,整个插件就基本完成了

六,这里贴出如上三个事件的代码
1,addCSS():

//add css to the dBox 
function addCSS() { 
var pos = setPosition(); 
$("#dBox").css({ "left": pos[0], "top": pos[1], "width": opts.width + "px", "height": opts.height + "px" }); 
if (opts.overlay) { 
var wh = getPageSize(); 
$(dBoxBG).appendTo("body").css({ "opacity": opts.opacity, "width": wh[0], "height": wh[1] }); 
} 
}

在这个addCSS中,还有两个功能需要实现,以下代码:
//calc the size of the page to put the mask layer cover the whole document 
function getPageSize() { 
if ($(window).height() > $(document).height()) { 
h = $(window).height(); 
} else { 
h = $(document).height(); 
} 
w = $(window).width(); 
return Array(w, h); 
} 
//calc the position of the dBox to put the dBox in the center of current window 
function setPosition() { 
if (opts.setPos) { 
l = opts.left; 
t = opts.top; 
} else { 
var w = opts.width; 
var h = opts.height; 
var width = $(document).width(); 
var height = $(window).height(); 
var left = $(document).scrollLeft(); 
var top = $(document).scrollTop(); 
var t = top + (height / 2) - (h / 2); 
var l = left + (width / 2) - (w / 2); 
} 
return Array(l, t); 
}

2,drag():

//drag the dBox 
//this event contains four events(handle.mousedown,move,out,up) 
function drag() { 
var dx, dy, moveout; 
var handle = $("#dBox").find("#d_head>#d_title").css('cursor', 'move'); 
handle.mousedown(function (e) { 
//cal the distance between e and dBox 
dx = e.clientX - parseInt($("#dBox").css("left")); 
dy = e.clientY - parseInt($("#dBox").css("top")); 
//bind mousemove event and mouseout event to the dBox 
$("#dBox").mousemove(move).mouseout(out).css({ "opacity": opts.opacity }); 
handle.mouseup(up); 
}); 
move = function (e) { 
moveout = false; 
win = $(window); 
var x, y; 
if (e.clientX - dx < 0) { 
x = 0; 
} else { 
if (e.clientX - dx > (win.width() - $("#dBox").width())) { 
x = win.width() - $("#dBox").width(); 
} else { 
x = e.clientX - dx; 
} 
} 
if (e.clientY - dy < 0) { 
y = 0; 
} else { 
y = e.clientY - dy; 
} 
$("#dBox").css({ 
left: x, 
top: y 
}); 
} 
out = function (e) { 
moveout = true; 
setTimeout(function () { 
moveout && up(e); 
}, 10); 
} 
up = function (e) { 
$("#dBox").unbind("mousemove", move).unbind("mouseout", out).css("opacity", 1); 
handle.unbind("mouseup", up); 
} 
}

3,dBoxRemove():
//close the dBox 
function dBoxRemove() { 
if ($("#dBox")) { 
$("#dBox").stop().fadeOut(200, function () { 
$("#dBox").remove(); 
if (opts.overlay) { 
$("#d_bg").remove(); 
$("#d_iframebg").remove(); 
} 
}); 
} 
}

到这里,插件制作基本完成,不过loading这个东东没有加上去。。。
另外还发现在ie6中,弹出的iframe高度和宽度都少了点,还有就是有遮罩层时,移动的时候不顺畅
还有其它问题欢迎讨论!
在线演示地址 http://demo.3water.com/js/dBox/dBox.htm
打包下载地址 http://xiazai.3water.com/201004/yuanma/dBox.rar

Javascript 相关文章推荐
Javascript的IE和Firefox兼容性汇编
Jul 01 Javascript
jQuery EasyUI 布局之动态添加tabs标签页
Nov 18 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
Dec 22 Javascript
详解Javascript中的原型OOP
Oct 12 Javascript
node.js入门学习之url模块
Feb 25 Javascript
Vue resource中的GET与POST请求的实例代码
Jul 21 Javascript
利用babel将es6语法转es5的简单示例
Dec 01 Javascript
javascript实现文件拖拽事件
Mar 29 Javascript
vuejs 动态添加input框的实例讲解
Aug 24 Javascript
Vue监听页面刷新和关闭功能
Jun 20 Javascript
vue-router为激活的路由设置样式操作
Jul 18 Javascript
谈一谈vue请求数据放在created好还是mounted里好
Jul 27 Javascript
Javascript中的相等与不等运算
Apr 25 #Javascript
下载网站打开页面后间隔多少时间才显示下载链接地址的代码
Apr 25 #Javascript
jQuery 打造动态渐变按钮 详细图文教程
Apr 25 #Javascript
javascript之学会吝啬 精简代码
Apr 25 #Javascript
一些相见恨晚的 JavaScript 技巧
Apr 25 #Javascript
Javascript 中的 &amp;&amp; 和 || 使用小结
Apr 25 #Javascript
js 禁用只读文本框获得焦点时的退格键
Apr 25 #Javascript
You might like
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
PHP实现的简单排列组合算法应用示例
2017/06/20 PHP
Laravel的Auth验证Token验证使用自定义Redis的例子
2019/09/30 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
Mootools 1.2教程 定时器和哈希简介
2009/09/15 Javascript
IE FF OPERA都可用的弹出层实现代码
2009/09/29 Javascript
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
2015/12/13 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
2016/01/05 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
switch语句的妙用(必看篇)
2016/10/03 Javascript
jQuery实现页面滚动时智能浮动定位
2017/01/08 Javascript
iscroll.js滚动加载实例详解
2017/07/18 Javascript
浅谈react前后端同构渲染
2017/09/20 Javascript
详解react-native WebView 返回处理(非回调方法可解决)
2018/02/27 Javascript
Vue中的$set的使用实例代码
2018/10/08 Javascript
JavaScript格式化json和xml的方法示例
2019/01/22 Javascript
Vue移动端实现图片上传及超过1M压缩上传
2019/12/23 Javascript
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
在Django的模型中添加自定义方法的示例
2015/07/21 Python
浅谈python日志的配置文件路径问题
2018/04/28 Python
Django 实现admin后台显示图片缩略图的例子
2019/07/28 Python
python matplotlib库绘制散点图例题解析
2019/08/10 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
PyQt5实现登录页面
2020/05/30 Python
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
新加坡时尚网上购物:Zalora新加坡
2016/07/26 全球购物
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
Ramy Brook官网:美国现代女装品牌
2019/06/18 全球购物
工商管理实习自我鉴定
2013/09/28 职场文书
初三新学期计划书
2014/05/03 职场文书
公司领导班子对照检查存在问题整改措施
2014/10/02 职场文书
2015年商场工作总结
2015/04/27 职场文书
Go语言实现Snowflake雪花算法
2021/06/08 Golang
Golang ort 中的sortInts 方法
2022/04/24 Golang