jquery插件封装指南

入门

编写一个jQuery插件开始于给jQuery.fn加入​​新的功能属性,此处添加的对象属性的名称就是你插件的名称:

jQuery.fn.myPlugin = function(){//你自己的插件代码};

用户非常喜欢的$符号哪里去了? 它仍然存在,但是,为了避免和其他JavaScript库冲突,我们最好将jQuery传递给一个自我执行的封闭程序,jQuery在此程序中映射为$符号,这样可以避免$号被其他库覆写。

(function ($) {$.fn.m​​yPlugin = function () {//你自己的插件代码};
})(jQuery);

在这个封闭程序中,我们可以无限制的使用$符号来表示jQuery函数。

环境

现在,我们可以开始编写实际的插件代码。 但是,在这之前,我们必须得对插件所处的环境有个概念。 在插件的范围里, this关键字代表了这个插件将要执行的jQuery对象, 这里容易产生一个普遍的误区,因为在其他包含callback的jQuery函数中,this关键字代表了原生的DOM元素。这常常会导致开发者误将this关键字无谓的包在jQuery中,如下所示。

(function ($) {$.fn.m​​yPlugin = function () {//此处没有必要将this包在$号中如$(this),因为this已经是一个jQuery对象。//$(this)等同于 $($('#element'));this.fadeIn('normal', function () {//此处callback函数中this关键字代表一个DOM元素});};
})(jQuery);$('#element').myPlugin();

基础知识

现在,我们理解了jQuery插件的基础知识,让我们写一个插件,做一些事情。

(function ($) {$.fn.m​​axHeight = function () {var max = 0;this.each(function () {max = Math.max(max, $(this).height());});return max;};
})(jQuery);var tallest = $('div').maxHeight(); //返回高度最大的div元素的高度

这是一个简单的插件,利用.height()返回页面中高度最大的div元素的高度。

维护Chainability

很多时候,一个插件的意图仅仅是以某种方式修改收集的元素,并把它们传递给链中的下一个方法。 这是jQuery的设计之美,是jQuery如此受欢迎的原因之一。 因此,要保持一个插件的chainability,你必须确保你的插件返回this关键字。

(function ($) {$.fn.lockDimensions = function (type) {return this.each(function () {var $this = $(this);if (!type || type == 'width') {$this.width($this.width());}if (!type || type == 'height') {$this.height($this.height());}});};
})(jQuery);$('div').lockDimensions('width').CSS('color', 'red');

由于插件返回this关键字,它保持了chainability,这样jQuery收集的元素可以继续被jQuery方法如.css控制。 因此,如果你的插件不返回固有的价值,你应该总是在其作用范围内返回this关键字。 此外,你可能会推断出,传递给插件的参数将会在插件的作用范围内被传递。 因此,在前面的例子,字符串’width’变成了插件的类型参数。

默认值和选项

对于比较复杂的和提供了许多选项可定制的的插件,最好有一个当插件被调用的时候可以被拓展的默认设置(通过使用$.extend)。 因此,相对于调用一个有大量参数的插件,你可以调用一个对象参数,包含你了你想覆写的设置。

(function ($) {$.fn.tooltip = function (options) {//创建一些默认值,拓展任何被提供的选项var settings = $.extend({'location': 'top','background-color': 'blue'}, options);return this.each(function () {// Tooltip插件代码});};
})(jQuery);$('div').tooltip({'location': 'left'
});

在这个例子中,调用tooltip插件时覆写了默认设置中的location选项,background-color选项保持默认值,所以最终被调用的设定值为:

{'location': 'left','background-color': 'blue'
}

这是一个很灵活的方式,提供一个高度可配置的插件,而无需开发人员定义所有可用的选项。

命名空间

正确命名空间你的插件是插件开发的一个非常重要的一部分。 正确的命名空间,可以保证你的插件将有一个非常低的机会被其他插件或同一页上的其他代码覆盖。 命名空间也使得你的生活作为一个插件开发人员更容易,因为它可以帮助你更好地跟踪你的方法,事件和数据。

插件方法

在任何情况下,一个单独的插件不应该在jQuery.fnjQuery.fn对象里有多个命名空间。

(function ($) {$.fn.tooltip = function (options) {// this};$.fn.tooltipShow = function () {// is};$.fn.tooltipHide = function () {// bad};$.fn.tooltipUpdate = function (content) {// !!!};})(jQuery);

这是不被鼓励的,因为它$.fn使$.fn命名空间混乱。 为了解决这个问题,你应该收集对象文本中的所有插件的方法,通过传递该方法的字符串名称给插件以调用它们。

(function ($) {var methods = {init: function (options) {// this},show: function () {// is},hide: function () {// good},update: function (content) {// !!!}};$.fn.tooltip = function (method) {// 方法调用if (methods[method]) {return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));} else if (typeof method === 'object' || !method) {return methods.init.apply(this, arguments);} else {$.error('Method' + method + 'does not exist on jQuery.tooltip');}};})(jQuery);//调用init方法
$('div').tooltip();//调用init方法
$('div').tooltip({foo: 'bar'
});// 调用hide方法
$('div').tooltip('hide');//调用Update方法
$('div').tooltip('update', 'This is the new tooltip content!');

这种类型的插件架构允许您封装所有的方法在父包中,通过传递该方法的字符串名称和额外的此方法需要的参数来调用它们。 这种方法的封装和架构类型是jQuery插件社区的标准,它被无数的插件在使用,包括jQueryUI中的插件和widgets。

事件

一个鲜为人知bind方法的功能即允许绑定事件命名空间。 如果你的插件绑定一个事件,一个很好的做法是赋予此事件命名空间。 通过这种方式,当你在解除绑定的时候不会干扰其他可能已经绑定的同一类型事件。 你可以通过追加命名空间到你需要绑定的的事件通过 <namespace>

(function ($) {var methods = {init: function (options) {return this.each(function () {$(window).bind('resize.tooltip', methods.reposition);});},destroy: function () {return this.each(function () {$(window).unbind('.tooltip');})},reposition: function () {//...},show: function () {//...},hide: function () {//...},update: function (content) {//...}};$.fn.tooltip = function (method) {if (methods[method]) {return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));} else if (typeof method === 'object' || !method) {return methods.init.apply(this, arguments);} else {$.error('Method ' + method + ' does not exist on jQuery.tooltip');}};})(jQuery);$('#fun').tooltip();
//一段时间之后... ...
$('#fun').tooltip('destroy');

在这个例子中,当tooltip通过init方法初始化时,它将reposition方法绑定到resize事件并给reposition非那方法赋予命名空间通过追加.tooltip。 稍后, 当开发人员需要销毁tooltip的时候,我们可以同时解除其中reposition方法和resize事件的绑定,通过传递reposition的命名空间给插件。 这使我们能够安全地解除事件的绑定并不会影响到此插件之外的绑定。

数据

通常在插件开发的时候,你可能需要记录或者检查你的插件是否已经被初始化给了一个元素。 使用jQuery的data方法是一个很好的基于元素的记录变量的途径。尽管如此,相对于记录大量的不同名字的分离的data, 使用一个单独的对象保存所有变量,并通过一个单独的命名空间读取这个对象不失为一个更好的方法。

(function ($) {var methods = {init: function (options) {return this.each(function () {var $this = $(this),data = $this.data('tooltip'),tooltip = $('<div />', {text: $this.attr('title')});// If the plugin hasn't been initialized yetif (!data) {/*Do more setup stuff here*/$(this).data('tooltip', {target: $this,tooltip: tooltip});}});},destroy: function () {return this.each(function () {var $this = $(this),data = $this.data('tooltip');// Namespacing FTW$(window).unbind('.tooltip');data.tooltip.remove();$this.removeData('tooltip');})},reposition: function () {// ...},show: function () {// ...},hide: function () {// ...},update: function (content) {// ...}};$.fn.tooltip = function (method) {if (methods[method]) {return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));} else if (typeof method === 'object' || !method) {return methods.init.apply(this, arguments);} else {$.error('Method ' + method + ' does not exist on jQuery.tooltip');}};})(jQuery);

将数据通过命名空间封装在一个对象中,可以更容易的从一个集中的位置读取所有插件的属性。

总结和最佳做法

编写jQuery插件允许你做出库,将最有用的功能集成到可重用的代码,可以节省开发者的时间,使开发更高效。 开发jQuery插件时,要牢记:

  • 始终包裹在一个封闭的插件:
(function($) {
/* plugin goes here */
})(jQuery);
  • 不要冗余包裹this关键字在插件的功能范围内
  • 除非插件返回特定值,否则总是返回this关键字来维持chainability 。
  • 传递一个可拓展的默认对象参数而不是大量的参数给插件。
  • 不要在一个插件中多次命名不同方法。
  • 始终命名空间的方法,事件和数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

synchronize原理

synchronized的三种应用方式 一. 修饰实例方法&#xff0c;作用于当前实例加锁&#xff0c;进入同步代码前要获得当前实例的锁。 二. 修饰静态方法&#xff0c;作用于当前类对象加锁&#xff0c;进入同步代码前要获得当前类对象的锁。 三. 修饰代码块&#xff0c;指定加锁对象&…

不能修改“System Roots”钥匙串

iOS mac添加证书 不能修改“System Roots”钥匙串错误 如图&#xff1a; 解决方式&#xff1a; 打开钥匙串---登录---&#xff0c;直接把证书拖过来 然后&#xff0c;查看--我的证书&#xff0c;里面&#xff0c;找到证书&#xff0c;即可

stylus在vue中的使用

stylus是一个css预处理器&#xff0c;比较流行的css预处理器有sass、less、stylus&#xff0c;它们都一样&#xff0c;都是css的语法糖&#xff0c;可以使用变量&#xff0c;可以有简单的逻辑&#xff0c;使css的开发效率更高&#xff0c;更易维护。stylus来自node社区&#xf…

未来产品的设计

Donald A. Norman继《情感化设计》之后&#xff0c;又一设计精品力作&#xff1a; 未来产品的设计样章试读及本书预定&#xff1a;http://www.china-pub.com/195642市场价 &#xff1a;&#xffe5;39.00 会员价 &#xff1a; &#xffe5;29.25(75折) 【作  者】(美)Donald…

vue-cli webpack 配置分析

目录结构 . ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.c…

css之字体图标

SVG与字体图标 SVG图片是矢量图片&#xff0c;不会随着图片的伸缩而影响质量&#xff0c;通常把只有一种颜色的图标做成SVG&#xff0c;通过SVG生成字体图标&#xff0c;放到项目中使用。 https://icomoon.io/是一个比较快捷的生成字体图标的线上工具&#xff0c;进入主页后&…

history.back(-1)和history.go(-1)的区别

history.back(-1):直接返回当前页的上一页&#xff0c;数据全部消息&#xff0c;是个新页面 history.go(-1):也是返回当前页的上一页&#xff0c;不过表单里的数据全部还在 history.back(0) 刷新 history.back(1) 前进 history.back(-1) 后退

研发阶段模拟接口数据

因为在vue-cli工程中需要创建很多.vue文件&#xff0c;我们希望创建vue文件和创建html、css、js文件一样右键即可选择创建&#xff0c;并且创建的文件中可预先写好模板代码。 webstorm-Preferences打开选项界面 选择File and Code Templates&#xff0c;点击绿色加号 填…

真实项目中 ThreadLocal 的妙用

一、什么是 ThreadLocal ThreadLocal 提供了线程的局部变量&#xff0c;每个线程都可以通过 set() 和 get() 来对这个局部变量进行操作&#xff0c;但不会和其他线程的局部变量冲突&#xff0c;实现了线程间的据隔离。 简单讲&#xff1a;一个获取用户的请求线程 A&#xff0c;…

css之flex布局

flex布局是css3中的重要布局方式&#xff0c;称为“弹性布局”&#xff0c;每次想到它主要是遇到元素垂直居中、元素宽高自适应的问题&#xff0c;这些问题在flex中都能过简单设置就解决&#xff0c;它更像是原生APP中的布局操作&#xff0c;布局不必写N多的盒模型代码来实现&a…

javascript对URL中的参数进行简单加密处理

javascript的api本来就支持Base64&#xff0c;因此我们可以很方便的来进行编码和解码。 var encodeData window.btoa("namexiaoming&age10")//编码 var decodeData window.atob(encodeData)//解码。 下面来个具体的例子来说明如何对url中参数进行转码&#xff…

Fibinary Numbers

http://acm.hust.edu.cn/vjudge/contest/view.action?cid30506#problem/V 题意&#xff1a;从右向左&#xff0c;每一个位数&#xff0c;分别表示一个fibonacci数&#xff0c;1表示有&#xff0c;0表示没有&#xff1b;求两个数的和&#xff0c;同样按照这种形式存储 #include…

移动web开发DRP问题

DPR dpr问题是移动端web开发上需要注意的问题&#xff0c;用大白话说就是&#xff0c;代码中所设置的像素值实际上是虚拟像素&#xff0c;手机屏幕上的像素实际为物理像素&#xff0c;原始的手机&#xff0c;虚拟像素与物理像素是1:1覆盖的&#xff0c;但随着移动端屏幕的技术发…

HTML元素title里面如何换行

在调试代码的时候我就遇到一个问题&#xff0c;HTML元素title里面通常只显示一行&#xff0c;那我想要他换行&#xff0c;就是多行显示&#xff0c;如何实现&#xff1f;JS代码里面比如Alert里面又该如何换行&#xff1f; 经过我的一番实验 要实现这种效果有几种方法&#xff0…

A20 GPIO中断类型差别结果迥异的问题思考

A20GPIO中断类型差别结果迥异的问题思考 最近在使用全志A20做开发时&#xff0c;发现在处理中断的时候&#xff0c;用电平触发模式&#xff0c;报中断比较乱&#xff0c;用边沿触发则很稳定&#xff0c;不会乱报。笔者感到比较困惑&#xff0c;笔者用电平触发写的code如下&…

div内图片和文字水平垂直居中

大小不固定的图片、多行文字的水平垂直居中 本文综述 想必写css的都知道如何让单行文字在高度固定的容器内垂直居中&#xff0c;但是您知道或者想过让行数不固定的文字在高度固定的容器内垂直居中呢&#xff1f;本文将会告诉你如何实现多行文字的垂直居中显示。 关于图片垂直居…

sticky-footer实现记录

sticky-footer是css中的一个经典问题&#xff1a; 当页面内容超出屏幕&#xff0c;页脚模块会像正常页面一样&#xff0c;被推到内容下方&#xff0c;需要拖动滚动条才能看到。 而当页面内容小于屏幕高度&#xff0c;页脚模块会固定在屏幕底部&#xff0c;就像是底边距为零的…

敏友的【敏捷个人】有感(3): 有感于“敏捷个人”讨论与练习

2010年我对个人管理进行了自己的一些思考&#xff0c;在2011年提出敏捷个人概念&#xff0c;并且在线上、线下进行了多次交流&#xff0c;在一些大会上也做过分享。现在&#xff0c;已经有很 多IT和非IT的敏友们知道并在践行敏捷个人&#xff0c;帮助自己更快的成长。我收到大家…

jQuery编写插件

引言&#xff1a; 在项目中不同页面经常要用到已经写好的交互&#xff0c;比如弹窗&#xff0c;比如下拉菜单&#xff0c;比如选项卡&#xff0c;比如删除... 此时如果每次都把代码copy一份无疑是一件比较麻烦并且无趣的事情&#xff0c;而且个人认为有些low了&#xff0c;我们…

webstorm中nodejs代码提示

preferences->languages&frameworks->Node.js and Npm中选择一个本地的node版本 preferences->languages&frameworks->JavaScript->Libraries 勾选node.js Core 回到代码