Fundamentos de jQuery

8.2. Crear una extensión básica

El código para realizar una extensión básica es la siguiente:

(function($){
    $.fn.myNewPlugin = function() {
        return this.each(function(){
            // realizar algo
        });
    };
}(jQuery));

La extensión del prototipo del objeto jQuery ocurre en la siguiente línea:

$.fn.myNewPlugin = function() { //...

La cual es encerrada en una función autoejecutable:

(function($){
    //...
}(jQuery));

Esta posee la ventaja de crear un alcance privado, permitiendo utilizar el signo dolar sin tener la preocupación de que otra biblioteca también este utilizando dicho signo.

Por ahora, internamente la extensión queda:

$.fn.myNewPlugin = function() {
    return this.each(function(){
        // realizar algo
    });
};

Dentro de ella, la palabra clave this hace referencia al objeto jQuery en donde la extensión es llamada.

var somejQueryObject = $('#something');

$.fn.myNewPlugin = function() {
    alert(this === somejQueryObject);
};

somejQueryObject.myNewPlugin(); // muestra un alerta con 'true'

El objeto jQuery, normalmente, contendrá referencias a varios elementos DOM, es por ello que a menudo se los refiere como una colección.

Para interactuar con la colección de elementos, es necesario realizar un bucle, el cual se logra fácilmente con el método each():

$.fn.myNewPlugin = function() {
    return this.each(function(){

    });
};

Al igual que otros métodos, each() devuelve un objeto jQuery, permitiendo utilizar el encadenado de métodos ($(...).css().attr()...). Para no romper esta convención, la extensión a crear deberá devolver el objeto this, para permitir seguir con el encadenamiento. A continuación se muestra un pequeño ejemplo:

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

// Ejemplo de utilización:
$('a').showLinkLocation();

La extensión modificará todos los enlaces dentro de la colección de elementos y les añadirá el valor de su atributo href entre paréntesis.

<!-- Antes que la extensión sea llamada: -->
<a href="page.html">Foo</a>

<!-- Después que la extensión es llamada: -->
<a href="page.html">Foo (page.html)</a>

También es posible optimizar la extensión:

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

El método append permite especificar una función de devolución de llamada, y el valor devuelto determinará que es lo que se añadirá a cada elemento. Note también que no se utiliza el método attr, debido a que la API nativa del DOM permite un fácil acceso a la propiedad href.

A continuación se muestra otro ejemplo de extensión. En este caso, no se requiere realizar un bucle en cada elemento ya que se delega la funcionalidad directamente en otro método jQuery:

(function($){
    $.fn.fadeInAndAddClass = function(duration, className) {
        return this.fadeIn(duration, function(){
            $(this).addClass(className);
        });
    };
}(jQuery));

// Ejemplo de utilización:
$('a').fadeInAndAddClass(400, 'finishedFading');