一个简单的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等比例缩小图片尺寸的实例
Feb 27 Javascript
JS 实现导航栏悬停效果(续2)
Sep 24 Javascript
node.js中的fs.fchmod方法使用说明
Dec 16 Javascript
React组件生命周期详解
Jul 03 Javascript
详解react-router4 异步加载路由两种方法
Sep 12 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
实例分析JS与Node.js中的事件循环
Dec 12 Javascript
Bootstrap table表格初始化表格数据的方法
Jul 25 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
Dec 11 jQuery
nuxt中使用路由守卫的方法步骤
Jan 27 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
Aug 17 Javascript
使用vue-router切换页面时实现设置过渡动画
Oct 31 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
15种PHP Encoder的比较
2007/04/17 PHP
php 文件上传后缀名与文件类型对照表(几乎涵盖所有文件)
2010/05/16 PHP
php下正则来匹配dede模板标签的代码
2010/08/21 PHP
php分页示例分享
2014/04/30 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
jquery实现文字由下到上循环滚动的实例代码
2013/08/09 Javascript
js数组循环遍历数组内所有元素的方法
2014/01/18 Javascript
邮箱下拉自动填充选择示例代码附图
2014/04/03 Javascript
jQuery中:header选择器用法实例
2014/12/29 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
JS组件系列之Gojs组件 前端图形化插件之利器
2017/11/29 Javascript
微信小程序实现传参数的几种方法示例
2018/01/10 Javascript
node.js制作一个简单的登录拦截器
2020/02/10 Javascript
node.js中process进程的概念和child_process子进程模块的使用方法示例
2020/02/11 Javascript
Javascript模块化机制实现原理详解
2020/04/02 Javascript
基于Vue.js+Nuxt开发自定义弹出层组件
2020/10/09 Javascript
vue项目开启Gzip压缩和性能优化操作
2020/10/26 Javascript
Vue SPA 首屏优化方案
2021/02/26 Vue.js
tornado捕获和处理404错误的方法
2014/02/26 Python
Python实现的简单hangman游戏实例
2015/06/28 Python
浅析Python中的多条件排序实现
2016/06/07 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
python读写csv文件实例代码
2019/07/05 Python
python FTP批量下载/删除/上传实例
2019/12/22 Python
Python第三方库的几种安装方式(小结)
2020/04/03 Python
Crabtree & Evelyn欧盟:豪华洗浴、身体和护发
2021/03/09 全球购物
什么是.net
2015/08/03 面试题
送餐员岗位职责范本
2014/02/21 职场文书
餐饮营销方案
2014/02/23 职场文书
我的中国梦演讲稿600字
2014/08/19 职场文书
2014党员批评和自我批评思想汇报
2014/09/21 职场文书
党员示范岗材料
2014/12/19 职场文书
8个JS的reduce使用实例和reduce操作方式
2021/10/05 Javascript
漫改真人电影「萌系男友是燃燃的橘色」公开先导视觉图
2022/03/21 日漫
docker-compose部署Yapi的方法
2022/04/08 Servers