一个简单的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 相关文章推荐
HTML-CSS群中单选引发的“事件”
Mar 05 Javascript
javascript写的日历类(基于pj)
Dec 28 Javascript
javascript学习笔记(十九) 节点的操作实现代码
Jun 20 Javascript
js setTimeout opener的用法示例详解
Oct 23 Javascript
JavaScript实现简单获取当前网页网址的方法
Nov 09 Javascript
BootStrap 附加导航组件
Jul 22 Javascript
js发送短信倒计时的简单实现方法
Sep 08 Javascript
web前端开发upload上传头像js示例代码
Oct 22 Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 Javascript
使用vue-router设置每个页面的title方法
Feb 11 Javascript
tracking.js实现前端人脸识别功能
Apr 16 Javascript
vue+iview实现文件上传
Nov 17 Vue.js
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
星际争霸 Starcraft 发展史
2020/03/14 星际争霸
用Apache反向代理设置对外的WWW和文件服务器
2006/10/09 PHP
php cache类代码(php数据缓存类)
2010/04/15 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
让焦点自动跳转
2006/07/01 Javascript
用JQUERY增删元素的代码
2012/02/14 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
详解JavaScript中数组和字符串的lastIndexOf()方法使用
2016/03/13 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
vue项目常用组件和框架结构介绍
2017/12/24 Javascript
手把手教你 CKEDITOR 4 扩展插件制作
2019/06/18 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
原生Vue 实现右键菜单组件功能
2019/12/16 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
2020/07/09 Javascript
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
Selenium chrome配置代理Python版的方法
2018/11/29 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
Python合并2个字典成1个新字典的方法(9种)
2019/12/19 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
2020/05/13 Python
python opencv实现直线检测并测出倾斜角度(附源码+注释)
2020/12/31 Python
html5构建触屏网站之touch事件介绍
2013/01/07 HTML / CSS
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
介绍java中初始化块的使用
2012/09/11 面试题
银行求职信个人范文
2013/12/16 职场文书
组织关系转移介绍信
2014/01/16 职场文书
教师党员批评与自我批评发言稿
2014/10/15 职场文书
中小学生学籍证明
2014/10/25 职场文书
大学生个人学年总结
2015/02/15 职场文书
政协常委会议主持词
2015/07/03 职场文书
2016年第十四个公民道德宣传日活动总
2016/04/01 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书
Python 高级库15 个让新手爱不释手(推荐)
2021/05/15 Python
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android