Introdução ao jQuery

por |

jQuery é uma biblioteca JavaScript desenvolvida para simplificar o scripting de HTML, selecionando elementos do DOM, lidando com eventos, e realizando requisições assíncronas. Também é possível criar e usar plugins de forma simples.

Instalação

Idealmente, o jQuery deve ser instalado através do npm, mas é possível baixar o arquivo .js minificado do jQuery no site oficial.

npm install jquery --save

Opcionalmente, se o uso do jQuery for limitado a, por exemplo, apenas chamadas AJAX, você pode excluir os módulos que não irá usar, e assim diminuir o tamanho do arquivo; para isso, será necessário instalar o Grunt. Logo após o npm terminar de baixar os arquivos, instale as dependências e execute o Grunt, listando os módulos que deseja excluir:

npm install
grunt custom:-css,-deprecated,-event,-wrap

Uma lista dos módulos está disponível no repositório oficial no GitHub: https://github.com/jquery/jquery#modules (em inglês). Tendo o arquivo .js do jQuery, o próximo passo é listá-lo no arquivo HTML:

…
<body>
    …

    <!-- Deferred JavaScript -->
    <script src="node_modules/jquery/dist/jquery.min.js"></script>
</body>
…

O código que fizer uso do jQuery deve ser chamado depois que o HTML estiver “pronto”:

$(function () { // O mesmo que: $(document).ready(function () {

    // $() é um atalho para jQuery()
    $('b.blue').removeClass('blue').css('color', 'gray');

});

Muitas bibliotecas JavaScript usam $ como nome de alguma função, e isso pode causar conflitos; para remediar isso, invoca-se $.noConflict(). Ainda será possível usar o atalho $ dentro do escopo da função:

$.noConflict();
jQuery(function ($) { // O mesmo que: jQuery(document).ready(function ($) {

    …

});

Seletores e chaining

O jQuery facilita a manipulação do DOM com o uso de seletores CSS e a técnica do chaining, que consiste em invocar vários métodos em um mesmo seletor, que por sua vez pode representar vários elementos numa página. No exemplo a seguir, todos os elementos b com a classe .blue são selecionados, e em seguida a classe é removida, e a cor do texto trocada para cinza:

$('b.blue').removeClass('blue').css('color', 'gray');

Em um exemplo mais complexo, é possível filtrar os elementos retornados (com .filter()), interagir com eles, voltar para seleção original (com .end()) e filtrar novamente outros elementos. Exemplo:

$('b')
    .filter('.blue').css('color', 'gray').end() // $("b.blue")
    .filter('.white').css('color', 'blue').end(); // $("b.white")

É possível também selecionar elementos filhos (com .find()). Exemplo:

$('article header')
    .find('h1').css('color', 'blue').end() // $("article header h1")
    .find('h2').css('color', 'silver').end(); // $("article header h2")

Além dos seletores da especificação do CSS, o jQuery possui outros seletores; uma lista completa pode ser encontrada em: https://api.jquery.com/category/selectors/jquery-selector-extensions/ (em inglês).

DOM

DOM (Document Object Model) é uma convenção para representar e interagir com objetos em documentos baseados em nós como, por exemplo, HTML, XML e SVG. O jQuery simplifica a interação, usando métodos de acesso a elementos, atributos e demais nós.

O método .css(), como já deve ter notado, simplifica a interação com o atributo style, e o .animate() permite animar seus valores. O método .data() interage com atributos data-, os quais podem armazenar objetos, strings, números, etc. Já os métodos .attr() e .prop() dão acesso direto aos atributos e propriedades, respectivamente. O valor de um atributo sempre será uma string, já uma propriedade varia. Segue um exemplo para entender a diferença entre esses dois últimos métodos:

$('input[type="checkbox"]').prop('checked', true); // marca todas as caixas de seleção
$('input[type="checkbox"]').prop('checked', false); // desmarca todas as caixas de seleção

$('input[type="checkbox"]').attr('checked', 'checked'); // marca todas as caixas de seleção
$('input[type="checkbox"]').removeAttr('checked'); // desmarca todas as caixas de seleção

$('div.blue').css({
    'color': 'white',
    'background-color': 'blue'
});
$('div.blue').prop('style'); // retorna um objeto com as propriedades CSS
$('div.blue').attr('style'); // retorna o valor do atributo style como string

Os métodos .attr(), .data(), .prop(), e .css() aceitam como parâmetro duas strings (nome e valor) ou um objeto para modificar os elementos selecionados, e uma string (nome) para retornar o valor.

É possível percorrer os elementos selecionados e interagir diferentemente com cada um, usando o método .each(). No exemplo a seguir, são selecionadas as imagens com links, e a partir delas, selecionados seus elementos pais (os links), e adicionados tooltips (atributo title) usando o texto alternativo das imagens (atributo alt):

// .each() é um loop que chama a função anônima para todos os elementos selecionados
$('a img').each(function () {

    // $(this) é o elemento selecionado da vez
    // .parent() é o elemento pai de <img> (<a>)
    $(this).parent().attr('title', $(this).attr('alt'));

});

Outros métodos importantes são .addClass() e .removeClass() (adiciona e remove classes), .append() (adiciona ou transfere elemento para o final), .prepend() (adiciona ou transfere elemento para o começo), .clone() (copia o elemento), .remove() (remove o elemento), .html() (substituie ou retorna os filhos como HTML), .text() (substitui ou retorna os elementos de texto) e .val() (retorna o valor de elementos input de texto e select). Como exemplo, considere os seguintes códigos (HTML e JavaScript):

<select name="continent">
    <option></option>
    <option>Europa</option>
    <option>Ásia</option>
    <option>África</option>
    <option selected>América</option>
    <option>Oceania</option>
</select>
$('select[name="continent"]').val(); // "América"
$('select[name="continent"] option:selected').remove(); // Remove a opção "América"
$('select[name="continent"]').prepend('<option>América do Sul</option>'); // Adiciona a opção "América do Sul"
$('select[name="continent"]').prepend('<option>América do Norte</option>'); // Adiciona a opção "América do Norte"

Para a lista completa de métodos, consulte a documentação oficial do jQuery.

Animações

O jQuery permite animar propriedades CSS através do método .animate(). Entretanto, por motivos de desempenho e flexibilidade, recomendo o uso de transições e animações CSS para animações simples, ou uma biblioteca de animação dedicada, como a GSAP para animações complexas; o .animate() é bem limitado (não é possível animar cores, por exemplo). A seguir, um exemplo onde um quadrado é esticado quando o ponteiro do mouse fica em cima.

Exemplo usando .animate():

$('div.animate').css({
    'background-color': 'blue',
    'width': '50px',
    'height': '50px'
}).on({
    'mouseenter': function () {
        $(this).stop().animate({ 'width': '150px' }, 500, 'ease');
        // .stop() pára qualquer animação em curso
    },
    'mouseleave': function () {
        $(this).stop().animate({ 'width': '50px' }, 500, 'ease');
        // O segundo parâmetro indica a duração da animação em milissegundos
        // O terceiro indica o nome da função (curva de aceleração)
    }
});

Exemplo usando transições CSS:

div.animate {
    background-color: blue;
    width: 50px;
    height: 50px;
    transition: all 0.5s ease;
}
div.animate:hover {
    width: 150px;
}

Eventos

Em um documento HTML, interações com os elementos resulta em “eventos” como, por exemplo, o clique. O jQuery fornece métodos para o registro de event listeners. O método .on() registra o event listener e o método .off() remove. O exemplo a seguir registra um event listener do clique em um link:

$('a.alert').on('click', function (event) {
    event.preventDefault(); // Previne que o navegador siga o link neste clique

    alert('Link clicado!');

    // Remove o event listener
    $(this).off('click');
});

Para forçar um evento, usa-se o método .trigger():

$('a.alert').trigger('click');

Para elementos criados dinamicamente, usa-se eventos delegados. O event listener é registrado em um elemento pai, e os filhos o acionam, sem a necessidade de adicionar event listeners para os elementos novos. Exemplo:

// Todos os a.alert dentro de p.delegated acionarão o event listener no clique
$('p.delegated').on('click', 'a.alert', function (event) {

    …

});

Para mais detalhes, consulte: http://learn.jquery.com/events/ (em inglês).

Requisições assíncronas

AJAX (Asynchronous JavaScript and XML) ou AJAJ (Asynchronous JavaScript and JSON) é uma técnica de programação assíncrona, que permite fazer requisições HTTP (ou FTP/file) pelo JavaScript, e atualizar o DOM, sem a necessidade de recarregar o documento. Atualmente é mais comum o uso de JSON nas requisições.

O jQuery simplifica as requisições através do método .ajax() (nativamente é usado o objeto XMLHttpRequest). Exemplo:

$.ajax({
    timeout: 60 * 1000, // Tempo permitido (em milissegundos) antes de abortar (opcional)
    url: 'http://',     // URL a ser requisitada
    type: 'GET',        // Método da requisição: GET (padrão) ou POST
    data: {}            // Parâmetros para passar na requisição (opcional)
})
    .done(function (data, textStatus, jqXHR) { // Executado quando for bem sucedido (opcional)
        console.log('Sucesso! Retorno: ' + data);
    })
    .fail(function (jqXHR, textStatus, errorThrown) { // Executado na ocasião de falha (opcional)
        switch (textStatus) {
            case 'timeout':
            case 'error':
            case 'abort':
            case 'parsererror':
                console.log('Falha! Status: ' + textStatus);
        }
    })
    .always(function (jqXHR, textStatus) { // Sempre executado (opcional)
        return;
    });

Dessa forma, é possível montar uma lista de resultados de uma pesquisa usando uma requisição assíncrona, por exemplo. Se o retorno estiver codificado como JSON ou XML, o jQuery reconhecerá automaticamente, e construirá um objeto. Exemplo:

$.ajax({
    url: 'http://example.com/post',
    data: { id: 8 } // "http://example.com/post?id=8"
})
    .done(function (data) {
        $(document).append(
            '<article>'
                + '<h1>' + data.title + '</h1>'
                + '<section>' + data.content + '</section>'
            + '</article>'
        );
    });

Para a lista completa de parâmetros, consulte: http://api.jquery.com/jquery.ajax/ (em inglês).

Plugins

O jQuery é extensível através de plugins. Com eles, é possível montar uma página de forma muito rápida, sem precisar “reinventar a roda”. Segue abaixo um modelo de plugin:

/*!
 * <nome-do-plugin>.js v1.0.0
 * https://github.com/<autor>/<nome-do-plugin>
 *
 * Copyright (c) <ano> <autor>
 * Released under the MIT License
 * http://opensource.org/licenses/MIT
 */

(function (factory) {
    'use strict';

    if (typeof exports !== 'undefined') {
        // Uso com módulos CommonJS
        module.exports = factory(require('jquery'));
    } else if (typeof define === 'function' && define.amd) {
        // Uso com módulos AMD
        define(['jquery'], factory);
    } else {
        // Uso com jQuery global
        factory(jQuery);
    }

}(function ($) {
    'use strict';

    $.fn.nomeDoPlugin = function (options) {
        var settings = $.extend({}, $.fn.nomeDoPlugin.defaults, options);

        // Aqui vai a ação específica do plugin…
        if (settings.auto === true) {
            this.append('<p>Olá, Mundo!</p>');
        } else {
            console.log('Olá, Mundo!');
        }

        return this; // Obrigatório para uso em chaining
    };

    // Configurações padrão do plugin
    $.fn.nomeDoPlugin.defaults = {
        auto: true
    };

}));

E o possível uso do plugin:

$(function () {

    $('body').nomeDoPlugin({ auto: false });

});

Meus plugins favoritos:

slick
carrosséis responsivos, usando animações CSS
Magnific Popup
modais responsivos, com suporte a galerias, usando animações CSS
Parsley
validação de formulários
jQuery Mask Plugin
máscaras para campos de texto