jQuery / Seletor / :nth-child() - Selecionar posições an+b
No jQuery, :nth-child(an+b) seleciona elementos irmãos nas posições que correspondem a uma fórmula, contando a partir de um em cada pai. p:nth-child(2) significa um p que é o segundo filho do tipo elemento, e não o segundo p. Use :nth-of-type(2) para o segundo irmão p ou .eq(1) para o segundo elemento de um conjunto já selecionado.
Contar a partir de um e incluir outras tags
A documentação de :nth-child() segue as regras CSS de posição entre irmãos. A contagem recomeça para cada pai e inclui outras tags. Espaços de texto e comentários não são elementos. Elementos ocultos continuam ocupando posições enquanto permanecem no documento; portanto, a ordem visível não basta.
Se um pai contém h2, p, p, p:nth-child(1) fica vazio e p:nth-child(2) seleciona o primeiro p. Ele não reúne os p antes de numerá-los. Restrinja o escopo a filhos diretos com >, como no exemplo.
Interpretar an+b e fórmulas comuns
Na definição CSS de an+b, a e b são inteiros, e n assume inteiros não negativos como 0, 1 e 2. Apenas posições positivas resultantes correspondem. Zero e posições negativas não selecionam nada. -n+3 produz 3, 2, 1, as três primeiras posições; não conta de trás para a frente a partir do fim.
| Condição | Posições | Significado |
|---|---|---|
| 2 | 2 | Segundo elemento de cada pai |
| 2n ou even | 2, 4, 6, … | Posições pares |
| 2n+1 ou odd | 1, 3, 5, … | Posições ímpares |
| 3n+1 | 1, 4, 7, … | Cada terceira posição a partir de um |
| -n+3 | 1, 2, 3 | Primeiras três posições |
Colocar p antes da condição mantém apenas os p nessas posições. Se o quarto filho é span, p:nth-child(2n) o exclui, mas não o ignora para renumerar um p posterior como quarto.
Exemplo completo com tags misturadas
Salve todo o código em UTF-8 como nth-child-demo.html e abra no navegador. Não é necessário instalar nada, mas é preciso internet para carregar o arquivo oficial do jQuery pela rede de distribuição de conteúdo, ou CDN. O código usa 4.0.0; fórmulas, inserção, restauração e comparação foram executadas com 3.7.1 e 4.0.0.
A contém h2, p, p, span, p; B contém h2, p, p, p. O resultado lista os IDs dos p para comparar com as posições das tags.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sibling positions and formulas</title>
<style>
body { font: 16px/1.6 sans-serif; margin: 24px; }
.group { border: 1px solid #aaa; padding: 12px; margin: 12px 0; }
.group > * { display: block; margin: 6px 0; padding: 6px; }
.group > .marked { background: #fff0b3; outline: 2px solid #b56b00; }
button, select { padding: 8px; margin: 4px; }
</style>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
<h1>Sibling positions and formulas</h1>
<div id="groups">
<section class="group" id="group-a">
<h2>A heading</h2>
<p id="a1">A paragraph 1</p>
<p id="a2">A paragraph 2</p>
<span>A note</span>
<p id="a3">A paragraph 3</p>
</section>
<section class="group" id="group-b">
<h2>B heading</h2>
<p id="b1">B paragraph 1</p>
<p id="b2">B paragraph 2</p>
<p id="b3">B paragraph 3</p>
</section>
</div>
<label for="rule">Formula:</label>
<select id="rule">
<option value="2">2</option>
<option value="2n">2n (even)</option>
<option value="2n+1">2n+1 (odd)</option>
<option value="3n+1">3n+1</option>
<option value="-n+3">-n+3</option>
</select>
<button type="button" id="prepend">Prepend notice to A</button>
<button type="button" id="reset">Reset</button>
<output id="result" aria-live="polite"></output>
<script>
$(function () {
function refresh() {
$("#groups > .group > p").removeClass("marked");
const rule = $("#rule").val();
const $chosen = $("#groups > .group > p:nth-child(" + rule + ")");
$chosen.addClass("marked");
const ids = $chosen.map((_, item) => item.id).get().join(", ");
$("#result").text(`${ids || "none"} | ${$chosen.length}`);
}
$("#rule").on("change", refresh);
$("#prepend").on("click", function () {
if (!$("#extra").length) {
$("#group-a").prepend('<div id="extra">Notice</div>');
}
refresh();
});
$("#reset").on("click", function () {
$("#extra").remove();
$("#rule").val("2");
refresh();
});
refresh();
});
</script>
</body>
</html>
A fórmula inicial é 2. O segundo elemento de cada grupo é seu primeiro p: a1 e b1 ficam destacados.
a1, b1 | 2
- 2n produz
a1, b1, b3 | 3. O quarto elemento de A é span e não satisfaz p. - 2n+1 produz
a2, a3, b2 | 3. O h2 inicial fica de fora. - 3n+1 produz
b3 | 1. As posições 1 e 4 de A são h2 e span; apenas a quarta de B é p. - -n+3 produz
a1, a2, b1, b2 | 4: os p entre os primeiros três filhos do tipo elemento de cada pai. - Use Reset e depois Prepend notice to A. O div inserido no início torna h2 o segundo filho de A. Com fórmula 2, resta
b1 | 1. Cliques repetidos não geram duplicatas. - Reset remove somente o div acrescentado, restaura a fórmula 2 e consulta novamente. O conteúdo original e
a1, b1 | 2retornam.
Comparar :nth-of-type() e .eq()
Após Reset, execute este trecho no console de desenvolvimento. :nth-of-type() conta irmãos da mesma tag; .eq() conta o conjunto já selecionado a partir de zero.
const ids = $set => $set.map((_, item) => item.id).get().join(", ");
console.log(ids($("#groups > .group > p:nth-child(2)")));
console.log(ids($("#groups > .group > p:nth-of-type(2)")));
console.log(ids($("#groups > .group > p").eq(1)));
a1, b1
a2, b2
a2
A primeira linha retorna a1 e b1, segundos filhos do tipo elemento que são p. A segunda retorna a2 e b2, segundos p de cada pai. A última retorna apenas a2, no índice 1 do conjunto completo de p. Um índice negativo de .eq() conta a partir do fim do conjunto e difere de -n+3.
Documento dinâmico e resultados inesperados
Seleções não refletem automaticamente alterações do documento. Um conjunto com a1 e b1 salvo antes da inserção mantém esses elementos depois. Consulte novamente, como refresh, e remova os destaques antigos para refletir as posições atuais.
Se o resultado ficar vazio, verifique posições zero ou inexistentes, a tag real e títulos, avisos ou elementos ocultos intermediários. Em tabelas, examine também pais intermediários como tbody no modelo de objetos do documento, DOM. Se nada responder, confira primeiro o carregamento do jQuery em Network e os erros em Console.




