Fork me on GitHub

如何写自己的jQuery插件?

尽管现在前端技术发展飞速发展,各种技术迭代很快,但jQuery还是在一些企业站或者简单网页尝尝用到,本文记录一下学写jQuery插件的内容,愿新手共勉,共同进步!

jQuery插件写前了解

jQuery如何工作:jQuery对象方法

在我们编写自己的插件之前,我们必须先了解一下jQuery的工作原理。 看看这段代码:

$( "a" ).css( "color", "red" );

这是一些非常基本的jQuery代码,但你知道幕后发生了什么吗? 每当使用$函数选择元素时,它都会返回一个jQuery对象。 此对象包含您一直使用的所有方法(.css(),. click()等)以及适合您的选择器的所有元素。 jQuery对象从$ .fn对象获取这些方法。 该对象包含所有jQuery对象方法,如果我们想编写自己的方法,则还需要包含这些方法。

基本插件创作

假设我们想要创建一个插件,使一组检索到的元素中的文本变为绿色。 我们所要做的就是在$ .fn中添加一个名为greenify的函数,它就像任何其他jQuery对象方法一样可用。

$.fn.greenify = function() {
    this.css( "color", "green" );
};

$( "a" ).greenify(); // Makes all the links green.

请注意,使用this.css(),而不是$(this)。 这是因为我们的greenify函数是与.css()相同的,this就是代表jq取出来的元素集合。

链式操作

我们需要做的一些事情才能使我们的插件在环境中生存。 当您将五个或六个动作链式操作到一个选择器时,jQuery最好用的一个功能就是链式操作。 这是通过让所有jQuery对象方法再次返回原始jQuery对象来实现的(有一些例外:.width()在没有参数的情况下调用返回所选元素的宽度,并且不可链式操作)。 让我们的插件可以实现链式操作需要一行代码:

$.fn.greenify = function() {
    this.css( "color", "green" );
      //返回this对象,即可实现链式操作
    return this;
}
 
$( "a" ).greenify().addClass( "greenified" );

$别名保护并添加范围

$变量在JavaScript库中非常流行,如果你在jQuery中使用另一个库,则必须使jQuery不使用$with jQuery.noConflict()。 但是,这会破坏我们的插件,因为它是在假设$是jQuery函数的别名的情况下编写的。 为了与其他插件一起使用,并且仍然使用jQuery $别名,我们需要将所有代码放在里面并立即调用函数表达式中,然后传递函数jQuery,并将参数命名为$

(function ( $ ) {

    $.fn.greenify = function() {
        this.css( "color", "green" );
        return this;
    };

}( jQuery ));

此外,立即调用函数的主要目的是允许我们拥有自己的私有变量。 假装我们想要一个不同的颜色绿色,我们想将它存储在一个变量中。

(function ( $ ) {
 
    var shade = "#556b2f";
 
    $.fn.greenify = function() {
        this.css( "color", shade );
        return this;
    };
 
}( jQuery ));

最大限度地减少插件占用空间

编写插件只占用$ .fn中的一个插槽是一种很好的做法。 这样可以降低插件被覆盖的可能性,以及插件覆盖其他插件的可能性。

(function( $ ) {
 
    $.fn.openPopup = function() {
        // Open popup code.
    };
 
    $.fn.closePopup = function() {
        // Close popup code.
    };
 
}( jQuery ));

提炼一个公共方法会更好,并使用参数来控制执行不同的操作。

(function( $ ) {
 
    $.fn.popup = function( action ) {
 
        if ( action === "open") {
            // Open popup code.
        }
 
        if ( action === "close" ) {
            // Close popup code.
        }
 
    };
 
}( jQuery ));

使用each()方法

典型的jQuery对象将包含对任意数量的DOM元素的引用,这就是jQuery对象通常被称为集合的原因。 如果要对特定元素进行任何操作(例如,获取数据属性,计算特定位置),则需要使用.each()循环遍历元素。

$.fn.myNewPlugin = function() {
 
    return this.each(function() {
        // Do something to each element here.
    });
 
};

请注意,我们返回.each()的结果而不是返回它。 因为.each()已经是可链式操作的,所以它返回它,然后我们再返回。 这是保持可链式操作的一种比我们迄今为止所做的更好的方法。

接受选项

随着您的插件变得越来越复杂,最好通过接受选项来使您的插件可自定义。 最简单的方法是使用对象文字,特别是如果有很多选项的话。 让我们更改我们的greenify插件以接受一些选项。

(function ( $ ) {
 
    $.fn.greenify = function( options ) {
 
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            color: "#556b2f",
            backgroundColor: "white"
        }, options );
 
        // Greenify the collection based on the settings variable.
        return this.css({
            color: settings.color,
            backgroundColor: settings.backgroundColor
        });
 
    };
 
}( jQuery ));

使用#556b2f的颜色默认值被$ .extend()覆盖为橙色。

$( "div" ).greenify({
    color: "orange"
});

以下是使用我们讨论过的一些技术的小插件示例:

这个方便的插件遍历集合中的所有锚点,并在括号中附加href属性。

(function( $ ) {
 
    $.fn.showLinkLocation = function() {
 
        this.filter( "a" ).each(function() {
            var link = $( this );
            link.append( " (" + link.attr( "href" ) + ")" );
        });
 
        return this;
 
    };
 
}( jQuery ));
 
// Usage example:
$( "a" ).showLinkLocation();
<!-- Before plugin is called: -->
<a href="page.html">Foo</a>
 
<!-- After plugin is called: -->
<a href="page.html">Foo (page.html)</a>

我们的插件可以优化:

(function( $ ) {
 
    $.fn.showLinkLocation = function() {
 
        this.filter( "a" ).append(function() {
            return " (" + this.href + ")";
        });
 
        return this;
 
    };
 
}( jQuery ));

我们使用.append()方法接受回调的功能,该回调的返回值将确定附加到集合中每个元素的内容。 另请注意,我们没有使用.attr()方法来检索href属性,因为本机DOM API使我们可以使用恰当命名的href属性轻松访问。

jQuery.fn.extend(object)

增加两个插件方法。

jQuery.fn.extend({
  check: function() {
    return this.each(function() { this.checked = true; });
  },
  uncheck: function() {
    return this.each(function() { this.checked = false; });
  }
});
$("input[type=checkbox]").check();
$("input[type=radio]").uncheck();
 

你可以拓展一个对象到jQuery的 prototype里去,这样的话就是插件机制了。

(function($) {
    $.fn.tooltip = function(options) {};
    //等价于 var
    tooltip = {
        function(options) {}
    };
    $.fn.extend(tooltip) = $.prototype.extend(tooltip) = $.fn.tooltip
})(jQuery);

jQuery.fn.extend()的调用把方法扩展到了对象的prototype上,所以实例化一个jQuery对象的时候,它就具有了这些方法,在jQuery.JS中到处体现这一点。

Object jQuery.extend( target, object1, [objectN])

用一个或多个其他对象来扩展一个对象,返回被扩展的对象

jQuery.extend(object)
为jQuery类添加类方法,可以理解为添加静态方法。如:
jQuery.extend({
	min: function(a, b) { return a < b ? a : b; },
	max: function(a, b) { return a > b ? a : b; }
});
jQuery.min(2,3); //  2 
jQuery.max(4,5); //  5
jQuery.extend( target, object1, [objectN])
用一个或多个其他对象来扩展一个对象,返回被扩展的对象
var settings = { validate: false, limit: 5, name: "foo" }; 
var options = { validate: true, name: "bar" }; 
jQuery.extend(settings, options); 

结果:settings == { validate: true, limit: 5, name: "bar" }
jQuery.fn.extend(object);
对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。
jQuery.fn.extend = jQuery.prototype.extend
你可以拓展一个对象到jQuery的 prototype里去,这样的话就是插件机制了。
(function( $ ){
	$.fn.tooltip = function( options ) {
	};
	//等价于
	var tooltip = {
		function(options){
		}
	};

	$.fn.extend(tooltip) = $.prototype.extend(tooltip) = $.fn.tooltip;
})( jQuery );

插件通用模板

// 包一层匿名函数防止污染
;(function(window,$,undefined){
  $.fn.extend({
    // plugName
    'plugName': function(option){
      // option 是用户调用插件时候传入的参数
      // defaults 是插件的默认参数
      // opts 是根据用户传入的参数与默认值合并之后的实际参数
      var defaults = { 
          },
          opts = $.extend({}, defaults, option);

      //循环所有jq元素集合,执行这个回调函数,这里的this是一个元素集合,就是用jq获取的那个元素集合,所以要在这里循环一下执行回调
      this.each(function(){
        // 插件需要的任何操作
      });

      //返回jq对象里的每一个元素,可以进行链式操作,当然如果不希望在插件后继续链式操作也可以不返回这个this
      return this;
    }
  });
})(window,jQuery);

如何写一个jQuery插件:

  1. 把上面插件通用模板代码复制到一个新建的js文件里
  2. plugName改成插件名字
  3. 把插件逻辑变量写到变量defaults
  4. this.each的回调函数里写上插件的代码逻辑

这样一个简单的jQuery就搞定了,是不是非常简单!

posted @ 2019-06-27 22:46  较瘦  阅读(578)  评论(0编辑  收藏  举报
知识点文章整理