深入学习jquery源码之插件机制(一)

深入学习jquery源码之插件机制

jQuery最着名的一个方面是其广泛的插件生态系统。从表格排序到表单验证再到自动完成 - 如果需要它,很可能有人为它编写了一个插件。

jQuery插件的质量差异很大。许多插件都经过了广泛的测试和维护良好,但其他插件被匆忙创建然后被忽略。不止一些人未能遵循最佳做法。一些插件,主要是jQuery UI,由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()相同的对象的一部分。

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

$.fn.greenify = function() {
    this.css( "color", "green" );
    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();


 

猜你喜欢

转载自blog.csdn.net/qq_35029061/article/details/85203709