一个简单的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 相关文章推荐
js 分栏效果实现代码
Aug 29 Javascript
jquery.combobox中文api和例子,修复了上面的小bug
Mar 28 Javascript
js网页实时倒计时精确到秒级
Feb 10 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
Jun 15 Javascript
显示今天的日期js代码(阳历和农历)
Sep 30 Javascript
简介JavaScript中的getUTCFullYear()方法的使用
Jun 10 Javascript
很棒的js选项卡切换效果
Jul 15 Javascript
Vue学习笔记进阶篇之过渡状态详解
Jul 14 Javascript
vue解决跨域路由冲突问题思路解析
Nov 03 Javascript
js中apply和Math.max()函数的问题及区别介绍
Mar 27 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
May 09 Javascript
JavaScript隐式类型转换代码实例
May 29 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
这部番真是良心,画质好到像风景区,剧情让人跟着小公会热血沸腾
2020/03/10 日漫
php 图像函数大举例(非原创)
2009/06/20 PHP
PHP程序级守护进程的实现与优化的使用概述
2013/05/02 PHP
PHP获取栏目的所有子级和孙级栏目的ID号示例
2014/04/01 PHP
几个优化WordPress中JavaScript加载体验的插件介绍
2015/12/17 PHP
php swoole多进程/多线程用法示例【基于php7nts版】
2019/08/12 PHP
js获得地址栏?问号后参数的方法
2013/08/08 Javascript
JavaScript 函数惰性载入的实现及其优点介绍
2013/08/12 Javascript
js仿百度贴吧验证码特效实例代码
2014/01/16 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
js封装可使用的构造函数继承用法分析
2015/01/28 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
浅谈javascript的闭包
2017/01/23 Javascript
JS仿淘宝搜索框用户输入事件的实现
2017/06/19 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
2017/06/20 Javascript
Vue2.0基于vue-cli+webpack父子组件通信(实例讲解)
2017/09/14 Javascript
JavaScript实现的超简单计算器功能示例
2017/12/23 Javascript
浅谈React前后端同构防止重复渲染
2018/01/05 Javascript
react配合antd组件实现的管理系统示例代码
2018/04/24 Javascript
JS闭包经典实例详解
2018/12/20 Javascript
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
python 将md5转为16字节的方法
2018/05/29 Python
Python调用C语言的实现
2019/07/26 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
如何在VSCode上轻松舒适的配置Python的方法步骤
2019/10/28 Python
Python FtpLib模块应用操作详解
2019/12/12 Python
Python使用文件操作实现一个XX信息管理系统的示例
2020/07/02 Python
html5 初试 indexedDB(推荐)
2016/07/21 HTML / CSS
简单的项目建议书模板
2014/03/12 职场文书
爱心活动计划书
2014/04/26 职场文书
蛋糕店创业计划书范文
2014/09/21 职场文书
党的群众路线教育实践活动查摆剖析材料
2014/10/10 职场文书
三方股份合作协议书
2014/10/13 职场文书
大学生学习新党章思想汇报
2014/10/25 职场文书
新学期主题班会
2015/08/17 职场文书