前端易小白_未来往事

JQuery 插件的编写

WEB前端

jquery的插件机制

为了方便用户创建插件,jquery提供了$.extend()和$.fn.extend()方法。
$.extend(object) ,用于扩展jQuery类本身,也就是用来在jQuery类/命名空间上增加新函数,或者叫静态方法.
例如 jquery内置的 ajax方法都是用$.ajax()这样调用的,有点像 “类名.方法名” 静态方法的调用方式。

  1. $.extend({
  2. minValue: function (a, b) {
  3. // 比较两个值,返回最小值
  4. return a < b ? a : b;
  5. }
  6. });
  7. //调用
  8. var i = 100; j = 101;
  9. var min_value = $.minValue(i, j); // min_value 等于 100
  1. $.extend([deep], target, object1, [objectN]);
  2. 用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
  3. 参数
  4. deep:可选。如果设为true,则递归合并。
  5. target:待修改对象,如果不指定target,则给jQuery命名空间本身进行扩展。
  6. obj1:待合并到第一个对象的对象
  7. objectN:可选。待合并到第一个对象的对象。
  1. 例:
  2. var obj1 = { a: false, b: 1, c: "abc" };
  3. var obj2 = { a: true, c: "def" };
  4. $.extend(obj1, obj2);
  5. // 输出 obj1 = { a: true, b: 1, c: "def" }
  1. 套路:
  2. var opts = $.extend({}, defaluts, options);
  3. // 用自定义插件参数去覆盖插件的默认参数

$.fn.extend(object)扩展 jQuery 元素集来提供新的方法(通常用来制作插件)。

  1. $.fn = $.prototype = {
  2.    init: function( selector, context ) {.....};
  3. };

原来 $.fn = $.prototype,也就是jQuery对象的原型。那jQuery.fn.extend()方法就是扩展jQuery对象的原型方法。

自执行的匿名函数/闭包

匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。

封装JQuery插件

接下来我们一起来写个 监听文本框,动态显示下拉选项 (类似搜索提示)插件

1.定一个闭包区域,防止插件”污染”

  1. //闭包限定命名空间
  2. (function ($) {
  3. // do something
  4. })(window.jQuery);

2.jQuery.fn.extend(object)扩展jquery 方法,制作插件

  1. //闭包限定命名空间
  2. (function ($) {
  3. $.fn.extend({
  4. getAjaxOption:function(options){
  5. // do something
  6. }
  7. });
  8. })(window.jQuery);

3.给插件默认参数,实现 插件的功能
//闭包限定命名空间

  1. (function ($) {
  2. $.fn.extend({
  3. getAjaxOption: function (options) {
  4. var opts = $.extend({}, defaluts, options); // 使用jQuery.extend 覆盖插件默认参数
  5. // 为body绑定事件,判断当点击别的区块,隐藏下拉选项区块
  6. $(document).on('click',function(event){
  7. event = window.event || event;
  8. var target = $(event.srcElement || event.target);
  9. var is_select = opts.container_class+' *,'+opts.container_class+','+opts.target_class+' *,'+opts.target_class;
  10. if(!target.is(is_select)){
  11. $(opts.container_class).hide();
  12. }
  13. })
  14. return this.each(function () { // 这里的this 就是 jQuery对象,这里 return 为了支持链式调用
  15. // 遍历所有选中的dom
  16. var $this = $(this); // 获取当前dom 的 jQuery对象,这里的this是当前循环的dom
  17. console.log(opts); // opts为当前所有的配置项
  18. // 接下来,在当前dom下生成下拉选项的dom元素
  19. $this.parent().css('position','relative');
  20. $this.addClass(opts.target_class.slice(1))
  21. .after('<div class="'+opts.container_class.slice(1)+'">'+
  22. '<div class="'+opts.container_class.slice(1)+'-box">'+
  23. '<div class="'+opts.no_data_class.slice(1)+'">'+opts.no_data_msg+'</div>'+
  24. '</div>'+
  25. '</div>');
  26. });
  27. }
  28. });
  29. //默认参数
  30. var defaluts = {
  31. container_class:'.container-options', // 下拉选项容器class
  32. target_class:'.ajaxOptionThis', // 当前dom的标识class
  33. option_class:'.item', // 生成的下拉选项的class
  34. no_data_class:'.no-data', // 无数据时对应项的class
  35. no_data_msg:'未找到相关数据', // 无数据时对应项显示的文字信息
  36. ajax_url:'******', // 请求的地址
  37. ajax_type:'get', // 请求的类型
  38. ajax_data:{ // 请求的额外参数
  39. city : 'zg',
  40. page : 1
  41. },
  42. ajax_keyword_name:'kw', // 请求的关键词的name值,value值固定为当前文本框的值
  43. };
  44. })(window.jQuery);

5.插件私有方法
有些时候,我们的插件需要一些私有方法,不能被外界访问。

  1. //私有方法,检测用户传进来的参数是否合法
  2. function isValid(options) {
  3. return !options || (options && typeof options === "object") ? true : false;
  4. }

6.公共方法 给别人来扩展你的插件 或者 返回一些回调api

  1. // 公共方法
  2. // 当点击了选项后的回调函数,$this为当前输入框,that为当前点击的选项,opts为插件的配置项集合
  3. $.fn.getAjaxOption.clickCallback = function ($this,that,opts) {}
  4. // 当ajax返回成功后执行的回调函数,$this为当前输入框,response为后端返回的数据,opts为插件的配置项集合
  5. $.fn.getAjaxOption.successCallback = function ($this,response,opts) {}

完整的插件代码如下:

  1. <style>
  2. .container-options{position:absolute;min-width:100%;left:0;background:#fff;z-index:1;display:none}
  3. .container-options .container-options-box{margin-top:-1px;border:1px solid #ccc;max-height:150px;overflow:auto}
  4. .container-options .item,.container-options .no-data{text-align:center;transition:all .3s;cursor:pointer;line-height:1;padding:8px 0;text-align:center}
  5. .container-options .item:hover{color:#fff;background:#eb6120}
  6. .container-options .no-data{display:none}
  7. </style>
  1. (function ($) {
  2. $.fn.extend({
  3. getAjaxOption: function (options) {
  4. //检测用户传进来的参数是否合法
  5. if (!isValid(options)) return this;
  6. var opts = $.extend({}, defaluts, options);
  7. $(document).on('click',function(event){
  8. event = window.event || event;
  9. var target = $(event.srcElement || event.target);
  10. var is_select = opts.container_class+' *,'+opts.container_class+','+opts.target_class+' *,'+opts.target_class;
  11. if(!target.is(is_select)){
  12. $(opts.container_class).hide();
  13. }
  14. })
  15. return this.each(function () {
  16. var $this = $(this);
  17. $this.parent().css('position','relative');
  18. $this.addClass(opts.target_class.slice(1))
  19. .after('<div class="'+opts.container_class.slice(1)+'">'+
  20. '<div class="'+opts.container_class.slice(1)+'-box">'+
  21. '<div class="'+opts.no_data_class.slice(1)+'">'+opts.no_data_msg+'</div>'+
  22. '</div>'+
  23. '</div>');
  24. // 为当前输入框绑定 事件监听,动态获取值
  25. $this.on('input',function(){
  26. var data = {};
  27. data[opts.ajax_keyword_name] = $.trim($this.val());
  28. data = $.extend({}, opts.ajax_data, data);
  29. if( data[opts.ajax_keyword_name].length <=0 ){ return false; }
  30. $.ajax({
  31. type:opts.ajax_type,
  32. url :opts.ajax_url,
  33. data: data,
  34. success: function(response){
  35. $.fn.getAjaxOption.successCallback($this,response,opts);
  36. }
  37. });
  38. })
  39. // 为下拉选项的每一项绑定click事件
  40. $(opts.container_class).on('click',opts.option_class,function(){
  41. $.fn.getAjaxOption.clickCallback($this,this,opts);
  42. })
  43. });
  44. }
  45. });
  46. //默认参数
  47. var defaluts = {
  48. // 容器dom
  49. container_class:'.container-options',
  50. target_class:'.ajaxOptionThis',
  51. option_class:'.item',
  52. no_data_class:'.no-data',
  53. no_data_msg:'未找到相关数据',
  54. ajax_url:'*****',
  55. ajax_type:'get',
  56. ajax_data:{
  57. city : 'zg',
  58. page : 1
  59. },
  60. ajax_keyword_name:'kw',
  61. };
  62. //公共方法
  63. $.fn.getAjaxOption.clickCallback = function ($this,that,opts) {
  64. $this.val($(that).text());
  65. $(opts.container_class).hide();
  66. }
  67. $.fn.getAjaxOption.successCallback = function ($this,response,opts) {
  68. $(opts.container_class).show().find(opts.option_class).remove();
  69. if(response.data == "no result"){
  70. $('.no-data',opts.container_class).show();
  71. }else{
  72. $('.no-data',opts.container_class).hide();
  73. var list = '';
  74. for (var i=0; i<response.data.list.length; i++){
  75. list += '<div class="'+opts.option_class.slice(1)+'" data-id="'+response.data.list[i].id+'">'+response.data.list[i].name+'</div>';
  76. }
  77. $(opts.container_class+'-box').append(list);
  78. }
  79. }
  80. //私有方法
  81. function isValid(options) {
  82. return !options || (options && typeof options === "object") ? true : false;
  83. }
  84. })(window.jQuery);
原文作者:前端易小白
原文地址:http://fity.cn/post/636.html
互联网技术更新较快,本站很多文章具有实效性,我会及时更新原文,但转载的文章无法通知更新。为了不给读者造成困惑或误导,请您在转载时保留此出处信息,尊重别人也是尊重自己。

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。