jQuery / Selector / :even - Selecionar elementos de índice par

O :even do jQuery seleciona os índices 0, 2 e 4 do conjunto encontrado: o primeiro, terceiro e quinto elementos. Ele está desaconselhado desde jQuery 3.4; use .even() para a mesma seleção em código novo. CSS :nth-child(even) conta outro conjunto e começa em um número diferente.

Versões e significado de :even e .even()

A documentação de :even explica os índices pares começando em zero e sua descontinuação recomendada desde 3.4. O método .even() foi acrescentado no jQuery 3.5. Alterar apenas a sintaxe mantendo um arquivo antigo 1.x não fornece esse método. Confira a versão realmente carregada na página.

Os exemplos foram executados em um navegador Windows com jQuery 3.7.1 e 4.0.0. :even funcionou nas duas versões verificadas. Desaconselhado não significa já removido; mesmo assim, use a alternativa recomendada ao criar ou atualizar código.

Índice par não é posição par entre filhos

Expressão Conjunto e início Posições selecionadas
:even ou .even() Conjunto atual, a partir de 0 0, 2, 4: primeiro, terceiro, quinto
:nth-child(even) Irmãos em cada pai, a partir de 1 Segundo, quarto, sexto filho
:nth-child(odd) Irmãos em cada pai, a partir de 1 Primeiro, terceiro, quinto filho

Em uma lista composta apenas por irmãos li, .even() e :nth-child(odd) podem coincidir. Ao selecionar li de várias listas, .even() conta o conjunto combinado. :nth-child() reinicia em cada pai e conta todos os elementos irmãos, não somente os da tag indicada.

Exemplo completo com duas listas

Salve todo o código em UTF-8 como even-demo.html e abra no navegador. É necessária conexão para carregar a distribuição oficial do jQuery. O exemplo fixa a versão 4.0.0 e não exige instalação de pacotes. A e B têm três elementos li cada.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Even indexes and sibling positions</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    .items { padding: 0; list-style: none; }
    .items li { padding: 8px 14px; border: 1px solid #ddd; }
    .marked { background: #fff0b3; }
    button { margin: 4px; padding: 8px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Even indexes and sibling positions</h1>
  <div id="groups">
    <ul class="items"><li id="a1">A1</li><li id="a2" class="keep">A2</li><li id="a3" class="keep">A3</li></ul>
    <ul class="items"><li id="b1" class="keep">B1</li><li id="b2">B2</li><li id="b3" class="keep">B3</li></ul>
  </div>
  <button type="button" id="combined">Combined .even()</button>
  <button type="button" id="per-parent">Each list .even()</button>
  <button type="button" id="css-even">CSS :nth-child(even)</button>
  <button type="button" id="reset">Reset</button>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      function show($chosen) {
        $("#groups li").removeClass("marked");
        $chosen.addClass("marked");
        const ids = $chosen.map((_, item) => item.id).get().join(", ");
        $("#result").text(`${ids || "none"} | ${$chosen.length}`);
      }
      $("#combined").on("click", () => show($("#groups li").even()));
      $("#per-parent").on("click", function () {
        let $chosen = $();
        $(".items").each(function () {
          $chosen = $chosen.add($(this).children("li").even());
        });
        show($chosen);
      });
      $("#css-even").on("click", () => show($("#groups li:nth-child(even)")));
      $("#reset").on("click", () => show($()));
      show($("#groups li").even());
    });
  </script>
</body>
</html>

Inicialmente A1, A3 e B2 ficam destacados, pois ocupam os índices 0, 2 e 4 dos seis elementos combinados.

a1, a3, b2 | 3

Comparar os controles e redefinir

  1. Combined .even() conta as listas juntas e produz a1, a3, b2 | 3.
  2. Each list .even() seleciona separadamente os filhos li de cada lista. Reiniciar por pai produz a1, a3, b1, b3 | 4.
  3. CSS :nth-child(even) seleciona o segundo filho de cada lista: a2, b2 | 2.
  4. Reset remove os destaques e mostra none | 0, sem excluir itens. Combined restaura o resultado inicial.

show remove o destaque anterior antes de marcar o novo resultado. A seleção por lista reúne seus resultados com add. Compare código e tela para entender se os índices são calculados no conjunto completo ou em cada pai.

Migrar de :even para .even()

Retire :even do seletor e chame .even() no objeto jQuery retornado pelo restante. Após abrir o exemplo ou pressionar Combined, execute este trecho na Console de desenvolvimento. Os primeiros dois resultados coincidem; o terceiro usa posições pares entre irmãos.

const ids = $set => $set.map((_, item) => item.id).get().join(", ");
console.log(ids($("#groups li:even")));
console.log(ids($("#groups li").even()));
console.log(ids($("#groups li:nth-child(even)")));
a1, a3, b2
a1, a3, b2
a2, b2

Trocar por :nth-child(even) muda o significado, não apenas a sintaxe. Defina se as faixas devem reiniciar por pai ou alternar sobre resultados filtrados. :even é uma extensão do jQuery e não deve ser usado diretamente como seletor de uma folha CSS.

Ordem dos filtros e mudanças posteriores

A2, A3, B1 e B3 têm a classe keep. $("#groups li.keep").even() filtra primeiro e seleciona A2 e B1. Já $("#groups li").even().filter(".keep") seleciona índices pares do conjunto inteiro e depois mantém keep, deixando apenas A3. A ordem muda o conjunto usado para calcular índices.

Seleções não são atualizadas automaticamente. Depois de acrescentar ou remover itens ou mudar filtros, execute novamente o seletor e .even() para refletir a ordem atual. Se não funcionar, confira a requisição em Network, os erros na Console e jQuery.fn.jquery. Verifique também se várias versões do jQuery foram carregadas.